package org.linlinjava.litemall.web.service;

import static org.linlinjava.litemall.db.beans.Constants.*;
import static org.linlinjava.litemall.web.util.WebResponseCode.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.github.yulichang.wrapper.MPJLambdaWrapper;
import lombok.SneakyThrows;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.linlinjava.litemall.core.notify.NoticeHelper;
import org.linlinjava.litemall.core.notify.netty.PushService;
import org.linlinjava.litemall.core.payment.DefaultCurType;
import org.linlinjava.litemall.core.payment.paypal.service.impl.GoodsPaypalServiceImpl;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.ResponseUtil.ListResponse;
import org.linlinjava.litemall.core.util.ResponseUtil.Response;
import org.linlinjava.litemall.db.beans.Constants;
import org.linlinjava.litemall.db.dao.LitemallOrderGoodsMapper;
import org.linlinjava.litemall.db.domain.*;
import org.linlinjava.litemall.db.dto.LitemallAccountBookFormDto;
import org.linlinjava.litemall.db.service.*;
import org.linlinjava.litemall.db.util.OrderHandleOption;
import org.linlinjava.litemall.db.util.OrderStatusUtil;
import org.linlinjava.litemall.db.util.OrderUtil;
import org.linlinjava.litemall.web.annotation.LoginUser;
import org.linlinjava.litemall.web.bo.OrderGoodsBo;
import org.linlinjava.litemall.web.constant.LiteamllWebConstants;
import org.linlinjava.litemall.web.dto.AdminCartDTO;
import org.linlinjava.litemall.web.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;

/**
 * web订单服务
 * 订单服务
 *
 * <p>
 * 订单状态：
 * 101 订单生成，未支付；102，下单后未支付用户取消；103，下单后未支付超时系统自动取消
 * 201 支付完成，商家未发货；202，订单生产，已付款未发货，但是退款取消；
 * 301 商家发货，用户未确认；
 * 401 用户确认收货； 402 用户没有确认收货超过一定时间，系统自动确认收货；
 *
 * <p>
 * 用户操作：
 * 当101用户未付款时，此时用户可以进行的操作是取消订单，或者付款操作
 * 当201支付完成而商家未发货时，此时用户可以取消订单并申请退款
 * 当301商家已发货时，此时用户可以有确认收货的操作
 * 当401用户确认收货以后，此时用户可以进行的操作是删除订单，评价商品，或者再次购买
 * 当402系统自动确认收货以后，此时用户可以删除订单，评价商品，或者再次购买
 *
 * <p>
 * 注意：目前不支持订单退货和售后服务
 *
 * @author yliyun
 * @date 2022/09/22
 */
@Service
public class WebOrderService {
    /**
     * 日志记录器
     */
    private final Log logger = LogFactory.getLog(WebOrderService.class);

    /**
     * 订单服务
     */
    @Autowired
    private LitemallOrderService orderService;

    @Autowired
    private LitemallOrderGoodsMapper litemallOrderGoodsMapper;

    @Autowired
    private GoodsPaypalServiceImpl paypalService;

    /**
     * 订单商品服务
     */
    @Autowired
    private LitemallOrderGoodsService orderGoodsService;
    /**
     * 产品服务
     */
    @Autowired
    private LitemallGoodsProductService productService;
    /**
     * 商品服务
     */
    @Autowired
    private LitemallGoodsService goodsService;
    /**
     * 店服务
     */
    @Autowired
    private LitemallShopService shopService;
    /**
     * 车服务
     */
    @Autowired
    private LitemallCartService cartService;
    /**
     * 产品规范服务
     */
    @Autowired
    private LitemallGoodsSpecificationService goodsSpecificationService;
    /**
     * 产品规范商品服务
     */
    @Autowired
    private LitemallGoodsSpecificationMerchandiseService goodsSpecificationMerchandiseService;
    /**
     * litemall税务服务
     */
    @Autowired
    private LitemallTaxService litemallTaxService;
    /**
     * litemall店地区服务
     */
    @Autowired
    private LitemallShopRegionService litemallShopRegionService;
    /**
     * litemall订单税务服务
     */
    @Autowired
    private LitemallOrderTaxService litemallOrderTaxService;
    /**
     * litemall订单现金服务
     */
    @Autowired
    private LitemallOrderCashService litemallOrderCashService;
    /**
     * litemall用户服务
     */
    @Autowired
    private LitemallUserService litemallUserService;

    @Autowired
    private LitemallIntegralLogService integralLogService;
    /**
     * litemall商品配件服务
     */
    @Autowired
    private LitemallGoodsAccessoryService litemallGoodsAccessoryService;
    /**
     * litemall购物车商品配件服务
     */
    @Autowired
    private LitemallCartGoodsAccessoryService litemallCartGoodsAccessoryService;
    /**
     * litemall订货配件服务
     */
    @Autowired
    private LitemallOrderGoodsAccessoryService litemallOrderGoodsAccessoryService;
    @Autowired
    private LitemallOrderFormulaMaterialService litemallOrderFormulaMaterialService;
    @Autowired
    private LitemallGoodsSpecificationService litemallGoodsSpecificationService;
    /**
     * 注意助手
     */
    @Autowired
    private NoticeHelper noticeHelper;
    /**
     * litemall商品服务
     */
    @Autowired
    private LitemallMerchandiseService litemallMerchandiseService;

    @Autowired
    private LitemallOrderMerchandiseService orderMerchandiseService;
    /**
     * litemall商店商品服务
     */
    @Autowired
    private LitemallShopMerchandiseService litemallShopMerchandiseService;
    /**
     * litemall订单商品服务
     */
    @Autowired
    private LitemallOrderMerchandiseService litemallOrderMerchandiseService;
    /**
     * litemall结算服务
     */
    @Autowired
    private LitemallSettlementService litemallSettlementService;
    /**
     * litemall订货房地产服务
     */
    @Autowired
    private LitemallOrderGoodsPropertyService litemallOrderGoodsPropertyService;
    /**
     * litemall充电消费服务
     */
    @Autowired
    private LitemallRechargeConsumptionService litemallRechargeConsumptionService;
    /**
     * litemall礼品卡用户服务
     */
    @Autowired
    private LitemallGiftCardUserService litemallGiftCardUserService;
    /**
     * litemall礼品卡用户日志服务
     */
    @Autowired
    private LitemallGiftCardUserLogService litemallGiftCardUserLogService;
    /**
     * 礼品卡服务
     */
    @Autowired
    private LitemallGiftCardService giftCardService;
    /**
     * litemall退款服务
     */
    @Autowired
    private LitemallRefundService litemallRefundService;

    @Autowired
    private LitemallCashScheduleService litemallCashScheduleService;
    /**
     * litemall退还商品服务
     */
    @Autowired
    private LitemallRefundGoodsService litemallRefundGoodsService;
    /**
     * litemall退还税收服务
     */
    @Autowired
    private LitemallRefundTaxService litemallRefundTaxService;
    /**
     * litemall帐服务
     */
    @Autowired
    private LitemallAccountBookService litemallAccountBookService;
    /**
     * 推动服务
     */
    @Autowired
    private PushService pushService;
    /**
     * 身份证服务
     */
    @Autowired
    private LumiereIdCardService idCardService;
    /**
     * 卢米埃三叶草支付日志服务
     */
    @Autowired
    private LumiereCloverPayLogService  lumiereCloverPayLogService;
    //各地时差
    @Value("${sys.difference}")
    private Long difference;


    @Autowired
    private LitemallGoodsSpecificationMerchandiseService litemallGoodsSpecificationMerchandiseService;

    /**
     * 订单列表
     *
     * @param userId   用户ID
     * @param showType 订单信息：
     *                 0，全部订单；
     *                 1，待付款；
     *                 2，待发货；
     *                 3，待收货；
     *                 4，待评价。
     * @param page     分页页数
     * @param limit     分页大小
     * @return 订单列表
     */
    /**
     public Object list(Integer shopId, Boolean isAll, Integer userId,Boolean today, Integer showType, Integer page, Integer limit, String sort, String order) {
     if (userId == null) {
     return ResponseUtil.unlogin();
     }

     List<Short> orderStatus = OrderUtil.orderStatus(showType);
     List<LitemallOrder> orderList;
     if(isAll != null && isAll){
     orderList = orderService.queryShopOrderByOrderStatus(shopId, today, orderStatus, page, limit, sort, order);
     }else{
     orderList = orderService.queryTodayByOrderStatus(userId, today, orderStatus, page, limit, sort, order);
     }

     List<Map<String, Object>> orderVoList = new ArrayList<>(orderList.size());
     for (LitemallOrder o : orderList) {
     Map<String, Object> orderVo = new HashMap<>();
     orderVo.put("id", o.getId());
     orderVo.put("orderSn", o.getOrderSn());
     orderVo.put("actualPrice", o.getActualPrice());
     orderVo.put("orderStatusText", OrderUtil.orderStatusText(o));
     orderVo.put("taxPrice", o.getTaxPrice());
     orderVo.put("orderStatus", o.getOrderStatus());
     orderVo.put("handleOption", OrderUtil.build(o));
     orderVo.put("orderSource", o.getOrderSource());
     orderVo.put("orderType", o.getOrderType());
     orderVo.put("updateTime", o.getUpdateTime());
     orderVo.put("payType", o.getPayType());
     orderVo.put("couponPrice", o.getCouponPrice());


     List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(o.getId());
     List<Map<String, Object>> orderGoodsVoList = new ArrayList<>(orderGoodsList.size());
     for (LitemallOrderGoods orderGoods : orderGoodsList) {
     Map<String, Object> orderGoodsVo = new HashMap<>();
     orderGoodsVo.put("id", orderGoods.getId());
     orderGoodsVo.put("goodsName", orderGoods.getGoodsName());
     orderGoodsVo.put("number", orderGoods.getNumber());
     orderGoodsVo.put("picUrl", orderGoods.getPicUrl());
     orderGoodsVo.put("specifications", orderGoods.getSpecifications());
     orderGoodsVoList.add(orderGoodsVo);
     }
     orderVo.put("goodsList", orderGoodsVoList);

     orderVoList.add(orderVo);
     }

     return ResponseUtil.okList(orderVoList, orderList);
     }*/

    /**
     * 列表
     * 订单列表
     *
     * @param shopId      店铺ID
     * @param userId      用户ID(可省)
     * @param today       是否今天
     * @param orderStatus 订单状态：0.新建;1.挂起;2.待支付;3.进行中;4.已取餐;5.已完成
     * @param page        分页页数
     * @param limit       分页大小
     * @param madeStatus  了状态
     * @param sort        排序
     * @param order       订单
     * @return 订单列表
     */
    public Response<ListResponse<OrderListResponseVO>> list(Integer shopId, Integer userId, Boolean today, Short orderStatus, List<Byte> madeStatus, Integer page, Integer limit, String sort, String order) {
        IPage<LitemallOrder> orderList = orderService.queryOrderSelective(shopId, userId, today, orderStatus, madeStatus, page, limit, sort, order);

        List orderVoList = new ArrayList(orderList.getRecords().size());
        for (LitemallOrder o : orderList.getRecords()) {
            OrderListResponseVO orderListVo = new OrderListResponseVO();
            BeanUtils.copyProperties(o,orderListVo);
            /*orderListVo.setId(o.getId());
            orderListVo.setShopId(o.getShopId());
            orderListVo.setOrderSn(o.getOrderSn());
            orderListVo.setSerialNo(o.getSerialNo());
            orderListVo.setOrderPrice(o.getOrderPrice());
            orderListVo.setActualPrice(o.getActualPrice());
            orderListVo.setGoodsPrice(o.getGoodsPrice());
            orderListVo.setTaxPrice(o.getTaxPrice());
            orderListVo.setOrderStatus(o.getOrderStatus());
            orderListVo.setOrderSource(o.getOrderSource());
            orderListVo.setOrderType(o.getOrderType());
            orderListVo.setPayType(o.getPayType());
            orderListVo.setMadeStatus(o.getMadeStatus());
            orderListVo.setOriginalSn(o.getOriginalSn());
            orderListVo.setIsRepeat(o.getIsRepeat());
            orderListVo.setCouponPrice(o.getCouponPrice());
            orderListVo.setSerinalNumber(o.getSerinalNumber());*/
            List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(o.getId());
            List<OrderListGoodsVO> goods = new ArrayList<>();
            String goodsNames = "";
            for (LitemallOrderGoods orderGoods : orderGoodsList) {
                OrderListGoodsVO orderListGoodsVo = new OrderListGoodsVO();
                orderListGoodsVo.setId(orderGoods.getId());
                orderListGoodsVo.setGoodsName(orderGoods.getGoodsName());
                orderListGoodsVo.setNumber(orderGoods.getNumber());
                orderListGoodsVo.setPicUrl(orderGoods.getPicUrl());
                orderListGoodsVo.setSellingPrice(orderGoods.getSellingPrice());
                orderListGoodsVo.setTaxPrice(orderGoods.getTaxPrice());
                orderListGoodsVo.setGoodsPrice(orderGoods.getSellingPrice().multiply(new BigDecimal(orderGoods.getNumber())));
                orderListGoodsVo.setPrice(orderGoods.getPrice());
                orderListGoodsVo.setRemark(StrUtil.isBlank(JSONUtil.toJsonStr(orderGoods.getRemark()))?null:JSONUtil.toJsonStr(orderGoods.getRemark()).replaceAll("=",":"));
                orderListGoodsVo.setRefundTime(orderGoods.getRefundTime());
                //查询规格辅料
                String[] specifications = orderGoods.getSpecifications();
                StringBuffer specAndAccessory = new StringBuffer(specifications[0]);
                //商品属性
                orderListGoodsVo.setSpecAndAccessory(specAndAccessory.toString());
                goodsNames += orderGoods.getGoodsName();
                goods.add(orderListGoodsVo);
            }
            /**
             * 因为数据库的类型对不上
             * 付款方式 1:余额 2:礼物卡，3:积分,4：信用卡
             * 支付方式(1:现金支付,2:礼物卡支付,3:Paypal支付,4:余额支付,5:Clover支付,6:积分兑换)
             *
             * pos展示的支付方式与app订阅下单后自动生成的订单支付方式与pos展示不符但app相符
             */
            if(o.getOrderSource()==4){
                switch (o.getPayType()){
                    case 1:{  orderListVo.setPayType(Constants.ORDER_PAY_TYPE_BALANCE);break;}
                    case 2:{  orderListVo.setPayType(Constants.ORDER_PAY_TYPE_CARD);break;}
                    case 3:{  orderListVo.setPayType(Constants.ORDER_PAY_TYPE_POINTS);break;}
                    case 4:{  orderListVo.setPayType(Constants.ORDER_PAY_TYPE_CLOVER);break;}
                }
            }
            orderListVo.setGoods(goods);
            orderListVo.setGoodsNames(goodsNames);
            orderListVo.setOrderDate(o.getAddTime().toString().replace("T", " "));
            orderVoList.add(orderListVo);
        }
        orderList.setRecords(orderVoList);
        return ResponseUtil.okPage(orderList);
    }


    /**
     * 订单详情
     *
     * @param shopId  商店id
     * @param orderSn 订单sn
     * @return {@link Response}
     */
    public Response orderDetails(Integer shopId, String orderSn) {
        LitemallOrder o = orderService.getOne(Wrappers.lambdaQuery(LitemallOrder.class).eq(LitemallOrder::getOrderSn, orderSn));
        OrderListResponseVO orderListVo = new OrderListResponseVO();
        //BeanUtils.copyProperties(orderList,o);
        orderListVo.setId(o.getId());
        orderListVo.setShopId(o.getShopId());
        orderListVo.setOrderSn(o.getOrderSn());
        orderListVo.setSerialNo(o.getSerialNo());
        orderListVo.setOrderPrice(o.getOrderPrice());
        orderListVo.setActualPrice(o.getActualPrice());
        orderListVo.setGoodsPrice(o.getGoodsPrice());
        orderListVo.setTaxPrice(o.getTaxPrice());
        orderListVo.setOrderStatus(o.getOrderStatus());
        orderListVo.setOrderSource(o.getOrderSource());
        orderListVo.setOrderType(o.getOrderType());
        orderListVo.setPayType(o.getPayType());
        orderListVo.setMadeStatus(o.getMadeStatus());
        orderListVo.setOriginalSn(o.getOriginalSn());
        orderListVo.setIsRepeat(o.getIsRepeat());
        orderListVo.setCouponPrice(o.getCouponPrice());
        orderListVo.setSerinalNumber(o.getSerinalNumber());

        List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(o.getId());
        List<OrderListGoodsVO> goods = new ArrayList<>();
        String goodsNames = "";
        for (LitemallOrderGoods orderGoods : orderGoodsList) {
            OrderListGoodsVO orderListGoodsVo = new OrderListGoodsVO();
            orderListGoodsVo.setId(orderGoods.getId());
            orderListGoodsVo.setGoodsName(orderGoods.getGoodsName());
            orderListGoodsVo.setNumber(orderGoods.getNumber());
            orderListGoodsVo.setPicUrl(orderGoods.getPicUrl());
            orderListGoodsVo.setSellingPrice(orderGoods.getSellingPrice());
            orderListGoodsVo.setTaxPrice(orderGoods.getTaxPrice());
            orderListGoodsVo.setGoodsPrice(orderGoods.getSellingPrice().multiply(new BigDecimal(orderGoods.getNumber())));
            orderListGoodsVo.setPrice(orderGoods.getPrice());
            orderListGoodsVo.setRemark(JSONUtil.toJsonStr(orderGoods.getRemark()));
            //查询规格辅料
            String[] specifications = orderGoods.getSpecifications();
            StringBuffer specAndAccessory = new StringBuffer(specifications[0]);
            //商品属性

            orderListGoodsVo.setSpecAndAccessory(specAndAccessory.toString());
            orderListGoodsVo.setRefundTime(orderGoods.getRefundTime());
            goodsNames += orderGoods.getGoodsName();
            goods.add(orderListGoodsVo);
        }
        orderListVo.setGoods(goods);
        orderListVo.setGoodsNames(goodsNames);
        orderListVo.setOrderDate(o.getAddTime().toString().replace("T", " "));
        return  ResponseUtil.ok(orderListVo);
    }

    /**
     * 库克列表
     * 订单列表
     *
     * @param shopId     店铺ID
     * @param madeStatus 制作状态：0:待制作,1:制作中,2:待取餐,3:已取餐
     * @param page       分页页数
     * @param limit      分页大小
     * @param sort       排序
     * @param order      订单
     * @return 订单列表
     */
    public Response<ListResponse<OrderCookListResponseVO>> cookList(Integer shopId, Byte madeStatus, Integer page, Integer limit, String sort, String order) {
        List<Byte> mStatus = new ArrayList<>();
        mStatus.add(madeStatus);
        IPage<LitemallOrder> orderList = orderService.queryOrderSelective(shopId, null, true, null, mStatus, page, limit, sort, order);
        List  orderVoList = new ArrayList<>(orderList.getRecords().size());
        for (LitemallOrder litemallOrder : orderList.getRecords()) {
            OrderCookListResponseVO orderListVo = new OrderCookListResponseVO();
            BeanUtils.copyProperties(litemallOrder, orderListVo);

            List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(litemallOrder.getId());
            List<OrderCookListGoodsVO> goods = new ArrayList<>();
            for (LitemallOrderGoods orderGoods : orderGoodsList) {
                OrderCookListGoodsVO orderListGoodsVo = new OrderCookListGoodsVO();
                BeanUtils.copyProperties(orderGoods, orderListGoodsVo);

                //查询规格辅料
                String[] specifications = orderGoods.getSpecifications();
                StringBuffer specAndAccessory = new StringBuffer(specifications[0]);
                //商品属性
                String property = getGoodsPropertyStr(orderGoods.getId());
                if (StringUtils.isNotBlank(property)) {
                    specAndAccessory.append("/").append(property);
                }
                String accessory = getGoodsAccessoryStr(orderGoods.getId());
                if (StringUtils.isNotBlank(accessory)) {
                    specAndAccessory.append("/").append(accessory);
                }
                orderListGoodsVo.setSpecAndAccessory(specAndAccessory.toString());

                goods.add(orderListGoodsVo);
            }
            orderListVo.setGoods(goods);

            orderVoList.add(orderListVo);
        }
        orderList.setRecords(orderVoList);
        return ResponseUtil.okPage(orderList);
    }

    /**
     * 回家数
     * 统计今日首页数字
     *
     * @param shopId   商店id
     * @param deviceNo 设备没有
     * @param userId   用户id
     * @return {@link Response}<{@link OrderHomeCountResponseVO}>
     */
    public Response<OrderHomeCountResponseVO> homeCount(Integer shopId, String deviceNo, Integer userId) {
        OrderHomeCountResponseVO response = new OrderHomeCountResponseVO();
        //计算今日订单数目
        List<Short> orderStatusLs = new ArrayList<Short>();
        orderStatusLs.add(Constants.ORDER_STATUS_UNPAID);
        orderStatusLs.add(Constants.ORDER_STATUS_ONGOING);
        orderStatusLs.add(Constants.ORDER_STATUS_PICKUP);
        orderStatusLs.add(Constants.ORDER_STATUS_FINISHED);
        Long orderCount = orderService.countOrder(shopId, orderStatusLs, true);
        Long hangCount = orderService.countOrderSelective(shopId, true, Constants.ORDER_STATUS_HANG, null);
        Long waitMadeCount = orderService.countOrderSelective(shopId, true, Constants.ORDER_STATUS_ONGOING, Constants.ORDER_MADE_STATUS_NEW);
        Long addCount = 0L;

        //获取当前机器的新建状态的订单
        LitemallOrder litemallOrder = orderService.getNewOrder(shopId, deviceNo, userId);
        LocalDateTime now = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        if (null != litemallOrder && now.compareTo(litemallOrder.getUpdateTime()) <= 0) {
            //判断是否为今日的新建订单
            List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(litemallOrder.getId());
            if (!CollectionUtils.isEmpty(orderGoodsList)) {
                addCount = Long.valueOf(orderGoodsList.size());
            }
        }
        response.setOrderCount(orderCount);
        response.setWaitMadeCount(waitMadeCount);
        response.setHangCount(hangCount);
        response.setAddCount(addCount);
        return ResponseUtil.ok(response);
    }

    /**
     * 状态数
     * 统计今日订单状态列表数字
     *
     * @param shopId 商店id
     * @return {@link Response}<{@link OrderStatusCountResponseVO}>
     */
    public Response<OrderStatusCountResponseVO> statusCount(Integer shopId) {
        OrderStatusCountResponseVO response = new OrderStatusCountResponseVO();
        Long unPaidCount = orderService.countOrderSelective(shopId, true, Constants.ORDER_STATUS_UNPAID, null);
        Long onGoingCount = orderService.countOrderSelective(shopId, true, Constants.ORDER_STATUS_ONGOING, null);
        Long pickedUpCount = orderService.countOrderSelective(shopId, true, Constants.ORDER_STATUS_PICKUP, null);
        Long finishedCount = orderService.countOrderSelective(shopId, true, Constants.ORDER_STATUS_FINISHED, null);

        response.setUnPaidCount(unPaidCount);
        response.setOnGoingCount(onGoingCount);
        response.setPickedUpCount(pickedUpCount);
        response.setFinishedCount(finishedCount);
        return ResponseUtil.ok(response);
    }

    /**
     * 创建或获取新
     * 创建或获取一个新建状态的订单(每台机器只有一个)
     *
     * @param shopId   店铺ID
     * @param deviceNo 设备编号
     * @param userId   用户id
     * @return 新建状态的订单
     */
    @Transactional
    public Response<OrderGetNewResponseVO> createOrGetNew(Integer shopId, String deviceNo, Integer userId) {
        //获取当前机器的新建状态的订单
        LitemallOrder litemallOrder = orderService.getNewOrder(shopId, deviceNo, userId);
        OrderGetNewResponseVO response = new OrderGetNewResponseVO();
        Integer maxSerialNo = orderService.getTodayMaxSerialNo(shopId);
        List<LitemallOrder> orders = getLastOrder(shopId);
        if (null == litemallOrder) {
            litemallOrder = new LitemallOrder();
            String orderSn = generateOrderSn();
            litemallOrder.setUserId(userId);
            litemallOrder.setShopId(shopId);
            litemallOrder.setDeviceNo(deviceNo);
            litemallOrder.setOrderSn(orderSn);
            litemallOrder.setSerialNo(maxSerialNo);

            litemallOrder.setOrderSource(Constants.ORDER_SOURCE_POS);//订单来源pos机
            litemallOrder.setOrderStatus(Constants.ORDER_STATUS_NEW);//订单状态--新建
            litemallOrder.setOrderType((byte) 3);
            litemallOrder.setShopOrder(true);



            if(orders.size() > 0 && orders.get(0) != null){
                LitemallOrder order  = orders.get(0);
                if(order.getSerinalNumber() == null){
                    litemallOrder.setSerinalNumber(0);
                }else{
                    litemallOrder.setSerinalNumber(order.getSerinalNumber() + 1);
                }
            }
            orderService.add(litemallOrder);

            BeanUtils.copyProperties(litemallOrder, response);
        } else {
            LocalDateTime now = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
            if (now.compareTo(litemallOrder.getUpdateTime()) >= 0) {
                //说明为昨天新建订单
                litemallOrder.setSerialNo(maxSerialNo + 1);
                orderService.updateById(litemallOrder);
                BeanUtils.copyProperties(litemallOrder, response);

                //更新响应的订单金额
                response.setOrderPrice(BigDecimal.ZERO);
                response.setTaxPrice(BigDecimal.ZERO);
                response.setGoodsPrice(BigDecimal.ZERO);
                response.setActualPrice(BigDecimal.ZERO);
                //删除昨天订单下所有的商品
                deleteAllGoods(litemallOrder.getId());
            } else {
                BeanUtils.copyProperties(litemallOrder, response);

                //查询订单商品
                List<OrderGetNewGoodsVO> goodsList = new ArrayList<>();
                response.setGoodsList(goodsList);
                Integer orderId = litemallOrder.getId();
                List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
                if (!CollectionUtils.isEmpty(orderGoodsList)) {
                    for (LitemallOrderGoods litemallOrderGoods : orderGoodsList) {
                        OrderGetNewGoodsVO goodsVo = new OrderGetNewGoodsVO();
                        BeanUtils.copyProperties(litemallOrderGoods, goodsVo);
                        //设置商品不含税总价
                        goodsVo.setGoodsPrice(litemallOrderGoods.getSellingPrice().multiply(new BigDecimal(litemallOrderGoods.getNumber())));
                        Integer orderGoodsId = litemallOrderGoods.getId();

                        //查询规格辅料
                        String[] specifications = litemallOrderGoods.getSpecifications();
                        StringBuffer specAndAccessory = new StringBuffer(specifications[0]);
                        //商品属性
                        String property = getGoodsPropertyStr(orderGoodsId);
                        if (StringUtils.isNotBlank(property)) {
                            specAndAccessory.append("/").append(property);
                        }
                        //商品辅料
                        String accessory = getGoodsAccessoryStr(orderGoodsId);
                        if (StringUtils.isNotBlank(accessory)) {
                            specAndAccessory.append("/").append(accessory);
                        }
                        goodsVo.setSpecAndAccessory(specAndAccessory.toString());

                        //设置商品的税费表
                        List<OrderGetNewTaxVO> taxs = new ArrayList<>();
                        //查询订单商品的税费表
                        List<LitemallOrderTax> orderTaxs = litemallOrderTaxService.queryByOrderIdAndOrderGoodsId(orderId, orderGoodsId);
                        if (!CollectionUtils.isEmpty(orderTaxs)) {
                            for (LitemallOrderTax orderTax : orderTaxs) {
                                OrderGetNewTaxVO orderGetNewTaxVo = new OrderGetNewTaxVO();
                                BeanUtils.copyProperties(orderTax, orderGetNewTaxVo);

                                taxs.add(orderGetNewTaxVo);
                            }
                        }
                        goodsVo.setTaxs(taxs);

                        goodsList.add(goodsVo);
                    }
                }


            }
        }

        return ResponseUtil.ok(response);
    }


    /**
     * 获取商品属性str
     * 获取商品的属性字符串
     *
     * @param orderGoodsId 订单商品id
     * @return {@link String}
     */
    private String getGoodsPropertyStr(Integer orderGoodsId) {
        StringBuffer sb = new StringBuffer();
        List<LitemallOrderGoodsProperty> propertyList = litemallOrderGoodsPropertyService.queryByOrderGoodsId(orderGoodsId);
        if (!CollectionUtils.isEmpty(propertyList)) {
            for (int i = 0; i < propertyList.size(); i++) {
                LitemallOrderGoodsProperty property = propertyList.get(i);
                sb.append(property.getValue());
                if (i < propertyList.size() - 1) {
                    sb.append("\r\n");
                }
            }
        }
        return sb.toString();
    }
    private List getGoodsPropertyList(Integer orderGoodsId) {
        List<LitemallOrderGoodsProperty> propertyList = litemallOrderGoodsPropertyService.queryByOrderGoodsId(orderGoodsId);
        if(!CollectionUtils.isEmpty(propertyList)) {
            List<Map> propertys = propertyList.stream().map(goodsProperty -> {
                Map map = CollUtil.newHashMap();
                map.put("name", goodsProperty.getName());
                map.put("value", goodsProperty.getValue());
                return map;
            }).collect(Collectors.toList());
            return propertys;
        }
        return CollUtil.newArrayList();
    }

    /**
     * 获得商品配件str
     * 获取商品的辅料字符串
     *
     * @param orderGoodsId 订单商品id
     * @return {@link String}
     */
    private String getGoodsAccessoryStr(Integer orderGoodsId) {
        StringBuffer sb = new StringBuffer();
        List<LitemallOrderGoodsAccessory> accessoryList = litemallOrderGoodsAccessoryService.findByOrderGoodsId(orderGoodsId);
        if (!CollectionUtils.isEmpty(accessoryList)) {
            for (int i = 0; i < accessoryList.size(); i++) {
                LitemallOrderGoodsAccessory accessory = accessoryList.get(i);
                sb.append(accessory.getAccessoryName());
                if (accessory.getNumber() >= 0) {
                    sb.append("+");
                }
                sb.append(accessory.getNumber());
                if (i < accessoryList.size() - 1) {
                    sb.append("\r\n");
                }
            }
        }
        return sb.toString();
    }

    private List getGoodsAccessoryList(Integer orderGoodsId) {
        List<LitemallOrderGoodsAccessory> accessoryList = litemallOrderGoodsAccessoryService.findByOrderGoodsId(orderGoodsId);
        if(!CollectionUtils.isEmpty(accessoryList)) {
            List<Map> accessorys = accessoryList.stream().map(accessory -> {
                Map map = CollUtil.newHashMap();
                map.put("name", accessory.getAccessoryName());
                map.put("num", accessory.getNumber());
                return map;
            }).collect(Collectors.toList());
            return accessorys;
        }
        return CollUtil.newArrayList();
    }

    /**
     * 生成订单sn
     *
     * @return {@link String}
     */
    private String generateOrderSn() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String now = df.format(LocalDateTime.now());
        return now + getRandomNum(4);
    }

    /**
     * 得到随机num
     *
     * @param num 全国矿工工会
     * @return {@link String}
     */
    private String getRandomNum(Integer num) {
        String base = "0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < num; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    /**
     * 挂
     * 订单挂起操作
     *
     * @param request 请求
     * @param shopId  商店id
     * @param userId  用户id
     * @return {@link Response}<{@link ListResponse}<{@link HandOrderVO}>>
     */
    @Transactional
    public Response<ListResponse<HandOrderVO>> hang(OrderHangRequestVO request, Integer shopId, Integer userId) {
        Integer orderId = request.getOrderId();
        LitemallOrder litemallOrder = orderService.findById(orderId);
        if (null == litemallOrder) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        if (Constants.ORDER_STATUS_NEW != litemallOrder.getOrderStatus()) {
            //非新建状态的订单不能被挂起
            return ResponseUtil.fail(ORDER_CAN_NOT_HANG, "只有新建状态的订单才能执行挂起操作");
        }

        List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
        if (CollectionUtils.isEmpty(orderGoodsList)) {
            return ResponseUtil.fail(ORDER_CAN_NOT_HANG, "空订单不能进行挂起操作");
        }
        litemallOrder.setOrderStatus(Constants.ORDER_STATUS_HANG);
        orderService.updateById(litemallOrder);

        //挂单信息
        List<HandOrderVO> vos = getHandOrderList(orderId, shopId, userId);
        noticeHelper.noticeShop(MESSAGE_TYPE_POS, JSON.toJSONString(litemallOrder), shopId);
        return ResponseUtil.okList(vos);
    }

    /**
     * 挂列表
     * 订单挂起操作
     *
     * @param shopId 商店id
     * @param userId 用户id
     * @return {@link Response}<{@link ListResponse}<{@link HandOrderVO}>>
     */
    @Transactional
    public Response<ListResponse<HandOrderVO>> hangList(Integer shopId, Integer userId) {

        //挂单信息
        List<HandOrderVO> vos = getHandOrderList(null, shopId, userId);

        return ResponseUtil.okList(vos);
    }


    /**
     * 恢复
     * 订单恢复操作
     *
     * @param shopId  商店id
     * @param request 请求
     * @param userId  用户id
     * @return {@link Response}<{@link OrderDetailResponseVO}>
     */
    @Transactional
    public Response<OrderDetailResponseVO> recover(Integer shopId, OrderRecoverRequestVO request, Integer userId) {
        Integer orderId = request.getOrderId();
        String deviceNo = request.getDeviceNo();
        LitemallOrder litemallOrder = orderService.findById(orderId);
        if (null == litemallOrder) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        if (!shopId.equals(litemallOrder.getShopId())) {
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "不合法操作");
        }
        if (Constants.ORDER_STATUS_HANG != litemallOrder.getOrderStatus()) {
            //只有挂起状态的订单才能执行恢复操作
            return ResponseUtil.fail(ORDER_CAN_NOT_RECOVER, "只有挂起状态的订单才能执行恢复操作");
        }

        //查询新建状态的订单
        LitemallOrder newOrder = orderService.getNewOrder(shopId, deviceNo, userId);
        if (null != newOrder) {
            List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
            if (CollectionUtils.isEmpty(orderGoodsList)) {
                //如果为空订单则删除
                orderService.deleteById(newOrder.getId());
            } else {
                //如果新建状态的订单不为空，则设置其订单状态为挂起
                newOrder.setOrderStatus(Constants.ORDER_STATUS_HANG);
                orderService.updateById(newOrder);
            }
        }

        //将该订单的状态改为新建
        litemallOrder.setOrderStatus(Constants.ORDER_STATUS_NEW);
        noticeHelper.noticeShop(MESSAGE_TYPE_POS, JSON.toJSONString(litemallOrder), shopId);
        //设置订单的设备编号为本设备
        litemallOrder.setDeviceNo(deviceNo);
        orderService.updateById(litemallOrder);

        return detail(orderId);
    }

    /**
     * 删除
     * 订单删除操作
     *
     * @param orderId 订单id
     * @return {@link Response}<{@link Object}>
     */
    @Transactional
    public Response<Object> delete(Integer orderId) {
        //删除订单
        orderService.deleteById(orderId);
        //删除订单商品
        orderGoodsService.deleteByOrderId(orderId);
        //删除订单商品属性
        litemallOrderGoodsPropertyService.deleteByOrderId(orderId);
        //删除订单商品辅料
        litemallOrderGoodsAccessoryService.deleteByOrderId(orderId);
        //删除订单商品税费
        litemallOrderTaxService.deleteByOrderId(orderId);

        return ResponseUtil.ok();
    }

    /**
     * 删除所有货物
     * 删除订单下所有商品操作
     *
     * @param orderId 订单id
     * @return {@link Response}<{@link Object}>
     */
    @Transactional
    public Response<Object> deleteAllGoods(Integer orderId) {
        LitemallOrder litemallOrder = orderService.findById(orderId);
        if (null == litemallOrder) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        if (Constants.ORDER_STATUS_NEW != litemallOrder.getOrderStatus()) {
            //非新建状态的订单不能删除所有商品
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "不合法操作");
        }

        //更新订单金额
        litemallOrder.setOrderPrice(BigDecimal.ZERO);
        litemallOrder.setTaxPrice(BigDecimal.ZERO);
        litemallOrder.setGoodsPrice(BigDecimal.ZERO);
        litemallOrder.setActualPrice(BigDecimal.ZERO);
        orderService.updateById(litemallOrder);

        //删除订单商品
        orderGoodsService.deleteByOrderId(orderId);
        //删除订单商品属性
        litemallOrderGoodsPropertyService.deleteByOrderId(orderId);
        //删除订单商品辅料
        litemallOrderGoodsAccessoryService.deleteByOrderId(orderId);
        //删除订单商品税费
        litemallOrderTaxService.deleteByOrderId(orderId);
        return ResponseUtil.ok();
    }

    /**
     * 被命令sn细节
     * 根据订单编号查询订单详情
     *
     * @param orderSn 订单编号
     * @return 订单详情
     */
    public Response<OrderDetailResponseVO> getDetailByOrderSn(String orderSn) {
        // 订单信息
        LitemallOrder litemallOrder = orderService.findBySn(orderSn);
        if (null == litemallOrder) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        OrderDetailResponseVO response = detail(litemallOrder, null);
        return ResponseUtil.ok(response);
    }

    /**
     * 细节
     * 订单详情
     *
     * @param orderId 订单ID
     * @return 订单详情
     */
    public Response<OrderDetailResponseVO> detail(Integer orderId) {
        // 订单信息
        LitemallOrder litemallOrder = orderService.findById(orderId);
        if (null == litemallOrder) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        OrderDetailResponseVO response = detail(litemallOrder, null);
        return ResponseUtil.ok(response);
    }

    /**
     * 细节和订单商品id
     *
     * @param orderId      订单id
     * @param orderGoodsId 订单商品id
     * @return {@link Response}<{@link OrderDetailResponseVO}>
     */
    public Response<OrderDetailResponseVO> detailAndOrderGoodsId(Integer orderId, Integer orderGoodsId) {
        // 订单信息
        LitemallOrder litemallOrder = orderService.findById(orderId);
        if (null == litemallOrder) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        OrderDetailResponseVO response = detail(litemallOrder, orderGoodsId);
        return ResponseUtil.ok(response);
    }


    /**
     * 细节
     *
     * @param litemallOrder litemall秩序
     * @param ogId          og id
     * @return {@link OrderDetailResponseVO}
     */
    private OrderDetailResponseVO detail(LitemallOrder litemallOrder, Integer ogId) {
        OrderDetailResponseVO response = new OrderDetailResponseVO();
        BeanUtils.copyProperties(litemallOrder, response);

        if (ogId != null) {
            response.setOrderGoodsId(ogId);
        }

        Integer orderId = litemallOrder.getId();
        //查询订单商品
        List<OrderDetailGoodsVO> goodsList = new ArrayList<>();
        List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
        if (!CollectionUtils.isEmpty(orderGoodsList)) {
            for (LitemallOrderGoods litemallOrderGoods : orderGoodsList) {
                OrderDetailGoodsVO goodsVo = new OrderDetailGoodsVO();
                BeanUtils.copyProperties(litemallOrderGoods, goodsVo);
                //设置商品不含税总价
                goodsVo.setGoodsPrice(litemallOrderGoods.getSellingPrice().multiply(new BigDecimal(litemallOrderGoods.getNumber())));
                goodsVo.setDiscountGoodsPrice(litemallOrderGoods.getDiscountPrice().multiply(new BigDecimal(litemallOrderGoods.getNumber())));
                Integer orderGoodsId = litemallOrderGoods.getId();

                //设置商品副标题
                Integer goodsId = litemallOrderGoods.getGoodsId();
                LitemallGoods goods = goodsService.findById(goodsId);
                goodsVo.setSubhead(goods.getSubhead());

                //设置商品规格信息
                OrderDetailGoodsSpecVO orderDetailGoodsSpecVo = new OrderDetailGoodsSpecVO();
                Integer specificationId = litemallOrderGoods.getSpecificationIds()[0];
                LitemallGoodsSpecification goodsSpecification = goodsSpecificationService.findById(specificationId);
                BeanUtils.copyProperties(goodsSpecification, orderDetailGoodsSpecVo);
                goodsVo.setSpec(orderDetailGoodsSpecVo);

                //查询规格辅料
                String[] specifications = litemallOrderGoods.getSpecifications();
                StringBuffer specAndAccessory = new StringBuffer(specifications[0]);

                //商品属性
                List<OrderDetailGoodsPropVO> props = new ArrayList<OrderDetailGoodsPropVO>();
                String property = getGoodsPropertyStrAndList(orderGoodsId, props);
                if (StringUtils.isNotBlank(property)) {
                    specAndAccessory.append("/").append(property);
                }
                goodsVo.setProps(props);

                //商品辅料
                List<OrderDetailGoodsAccessoryVO> accessorys = new ArrayList<OrderDetailGoodsAccessoryVO>();
                String accessory = getGoodsAccessoryStrAndList(orderGoodsId, accessorys);
                if (StringUtils.isNotBlank(accessory)) {
                    specAndAccessory.append("/").append(accessory);
                }
                goodsVo.setSpecAndAccessory(specAndAccessory.toString());
                goodsVo.setAccessorys(accessorys);

                //设置商品的税费表
                List<OrderDetailTaxVO> taxs = new ArrayList<>();
                //查询订单商品的税费表
                List<LitemallOrderTax> orderTaxs = litemallOrderTaxService.queryByOrderIdAndOrderGoodsId(orderId, orderGoodsId);
                if (!CollectionUtils.isEmpty(orderTaxs)) {
                    for (LitemallOrderTax orderTax : orderTaxs) {
                        OrderDetailTaxVO orderGetNewTaxVo = new OrderDetailTaxVO();
                        BeanUtils.copyProperties(orderTax, orderGetNewTaxVo);
                        taxs.add(orderGetNewTaxVo);
                    }
                }
                goodsVo.setTaxs(taxs);
                goodsList.add(goodsVo);
            }
        }

        //查询订单现金详情
        List<LitemallOrderCash> cashLs = litemallOrderCashService.queryByOrderId(orderId);
        if (!CollectionUtils.isEmpty(cashLs)) {
            OrderDetailCashVO cashDetail = new OrderDetailCashVO();
            BeanUtils.copyProperties(cashLs.get(0), cashDetail);
            response.setCashDetail(cashDetail);
        }

        //用户可用余额
        Integer userId = litemallOrder.getUserId();
        if (null != userId) {
            LitemallUser user = litemallUserService.findById(userId);
            response.setUserAvailableAmount(user.getAvailableAmount());
        }

        response.setGoodsList(goodsList);

        return response;
    }

    /**
     * 产品配件str和列表
     * 获取商品的辅料字符串，且设置商品辅料列表
     *
     * @param orderGoodsId 订单商品id
     * @param accessorys   附件
     * @return {@link String}
     */
    private String getGoodsAccessoryStrAndList(Integer orderGoodsId, List<OrderDetailGoodsAccessoryVO> accessorys) {
        StringBuffer sb = new StringBuffer();
        List<LitemallOrderGoodsAccessory> accessoryList = litemallOrderGoodsAccessoryService.findByOrderGoodsId(orderGoodsId);
        if (!CollectionUtils.isEmpty(accessoryList)) {
            for (int i = 0; i < accessoryList.size(); i++) {
                LitemallOrderGoodsAccessory accessory = accessoryList.get(i);
                sb.append(accessory.getAccessoryName());
                if (accessory.getNumber() >= 0) {
                    sb.append("+");
                }
                sb.append(accessory.getNumber());
                if (i < accessoryList.size() - 1) {
                    sb.append("\r\n");
                }
                LitemallGoodsAccessory litemallGoodsAccessory = litemallGoodsAccessoryService.findById(accessoryList.get(i).getAccessoryId());
                LitemallMerchandise litemallMerchandise = litemallMerchandiseService.findById(litemallGoodsAccessory.getMerchandiseId());
                OrderDetailGoodsAccessoryVO orderDetailGoodsAccessoryVo = new OrderDetailGoodsAccessoryVO();
                BeanUtils.copyProperties(accessory, orderDetailGoodsAccessoryVo);

                orderDetailGoodsAccessoryVo.setUnit(litemallMerchandise.getUnit());
                if(orderDetailGoodsAccessoryVo.getNumber() != 0){
                    accessorys.add(orderDetailGoodsAccessoryVo);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 获取商品属性str和列表
     * 获取商品的属性字符串，且设置商品属性列表
     *
     * @param orderGoodsId 订单商品id
     * @param props        道具
     * @return {@link String}
     */
    private String getGoodsPropertyStrAndList(Integer orderGoodsId, List<OrderDetailGoodsPropVO> props) {
        StringBuffer sb = new StringBuffer();
        List<LitemallOrderGoodsProperty> propertyList = litemallOrderGoodsPropertyService.queryByOrderGoodsId(orderGoodsId);
        if (!CollectionUtils.isEmpty(propertyList)) {
            for (int i = 0; i < propertyList.size(); i++) {
                LitemallOrderGoodsProperty property = propertyList.get(i);
                sb.append(property.getValue());
                if (i < propertyList.size() - 1) {
                    sb.append("\r\n");
                }

                OrderDetailGoodsPropVO orderDetailGoodsPropVo = new OrderDetailGoodsPropVO();
                BeanUtils.copyProperties(property, orderDetailGoodsPropVo);
                props.add(orderDetailGoodsPropVo);
            }
        }
        return sb.toString();
    }

    /**
     * 确认
     * 订单确认操作
     *
     * @param request 请求
     * @return {@link Response}<{@link OrderDetailResponseVO}>
     */
    @Transactional
    public Response<OrderDetailResponseVO> confirm(OrderConfirmRequestVO request) {
        Integer orderId = request.getOrderId();
        LitemallOrder litemallOrder = orderService.findById(orderId);
        if (null == litemallOrder) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        if (Constants.ORDER_STATUS_NEW != litemallOrder.getOrderStatus()) {
            //非新建状态的订单不能确认
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "不合法操作");
        }

        //修改订单状态为待支付
        litemallOrder.setOrderType(request.getOrderType());
        litemallOrder.setOrderStatus(Constants.ORDER_STATUS_UNPAID);
        orderService.updateById(litemallOrder);
        return detail(orderId);
    }

    /**
     * 更新了状态
     * 更新制作状态
     *
     * @param orderId    订单id
     * @param madeStatus 了状态
     * @return {@link Response}<{@link Object}>
     */
    @Transactional
    public Response<Object> updateMadeStatus(Integer orderId, Byte madeStatus) {
        LitemallOrder litemallOrder = orderService.findById(orderId);
        if (null == litemallOrder) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        if (Constants.ORDER_STATUS_ONGOING != litemallOrder.getOrderStatus()) {
            //进行中的订单才能进行操作
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "不合法操作");
        }
        if (litemallOrder.getMadeStatus() == madeStatus) {
            //重复操作
            return ResponseUtil.fail(ORDER_REPEAT_OPERATION, "重复操作");
        }
        if (litemallOrder.getIsRefund() && Constants.ORDER_MADE_STATUS_ONGOING == madeStatus) {
            //退款订单不可制作
            return ResponseUtil.fail(ORDER_REFUND_COOK_INVALID, "退款订单不可制作");
        }


        //如果为已取餐，则修改订单状态为已取餐
        if (Constants.ORDER_MADE_STATUS_PICKUP == madeStatus) {
            litemallOrder.setOrderStatus(Constants.ORDER_STATUS_PICKUP);

            //TODO 原料的扣减
            List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
            if (!CollectionUtils.isEmpty(orderGoodsList)) {
                for (LitemallOrderGoods litemallOrderGoods : orderGoodsList) {
                    Map<Integer, BigDecimal> merMap = caculateMerchandise(litemallOrderGoods, true);
                    for (Integer merchandiseId : merMap.keySet()) {
                        BigDecimal consumerNumber = merMap.get(merchandiseId).multiply(new BigDecimal(litemallOrderGoods.getNumber()));

                        //新增原料损耗记录
                        LitemallOrderMerchandise orderMerchandise = new LitemallOrderMerchandise();
                        orderMerchandise.setOrderId(orderId);
                        Integer shopId = litemallOrderGoods.getShopId();
                        orderMerchandise.setShopId(shopId);
                        orderMerchandise.setOrderGoodsId(litemallOrderGoods.getId());
                        orderMerchandise.setGoodsId(litemallOrderGoods.getGoodsId());
                        orderMerchandise.setGoodsName(litemallOrderGoods.getGoodsName());
                        orderMerchandise.setGoodsSn(litemallOrderGoods.getGoodsSn());
                        orderMerchandise.setMerchandiseId(merchandiseId);
                        LitemallMerchandise litemallMerchandise = litemallMerchandiseService.findById(merchandiseId);
                        orderMerchandise.setMerchandiseName(litemallMerchandise.getName());
                        orderMerchandise.setMerchandiseSn(litemallMerchandise.getMerchandiseSn());
                        orderMerchandise.setConsumerNumber(consumerNumber);
                        litemallOrderMerchandiseService.add(orderMerchandise);

                        //扣减原料
                        LitemallShopMerchandise litemallShopMerchandise = litemallShopMerchandiseService.queryByMerIdAndShopId(merchandiseId, shopId);
                        //计算基本单位的剩余原料
                        Double basicRemainNumber = new BigDecimal(litemallShopMerchandise.getBasicNumber()).subtract(consumerNumber).setScale(0, BigDecimal.ROUND_HALF_UP).doubleValue();
                        litemallShopMerchandise.setBasicNumber(basicRemainNumber);
                        //计算盘点单位的剩余原料
                        Double checkRemainNumber = basicRemainNumber / litemallMerchandise.getCheckRatio();
                        litemallShopMerchandise.setNumber(checkRemainNumber);
                        litemallShopMerchandiseService.updateById(litemallShopMerchandise);
                    }

                }
            }
        }

        //修改订单状态为待支付
        litemallOrder.setMadeStatus(madeStatus);
        orderService.updateById(litemallOrder);
        return ResponseUtil.ok();
    }

    /**
     * 贵司货物
     * 计算订单商品的原料损耗
     *
     * @param isConsumeRatio     是否计算原料损耗系数
     * @param litemallOrderGoods litemall订货
     * @return 原料损耗map <原料id，损耗的数量>
     */
    private Map<Integer, BigDecimal> caculateMerchandise(LitemallOrderGoods litemallOrderGoods, boolean isConsumeRatio) {
        //创建原料损耗map <原料id，损耗的数量>
        Map<Integer, BigDecimal> merMap = new HashMap<>();

        //计算规格原料
        Integer specId = litemallOrderGoods.getSpecificationIds()[0];
        List<LitemallGoodsSpecificationMerchandise> goodsSpecMerchandises = goodsSpecificationMerchandiseService.queryBySpecid(specId);
        for (LitemallGoodsSpecificationMerchandise goodsSpecMerchandise : goodsSpecMerchandises) {
            Integer merchandiseId = goodsSpecMerchandise.getMerchandiseId();
            BigDecimal number = new BigDecimal(goodsSpecMerchandise.getNumber());
            if (isConsumeRatio) {//计算消耗系数
                number = number.multiply(goodsSpecMerchandise.getConsumeRatio());
            }

            BigDecimal merNumber = merMap.get(merchandiseId);
            if (null == merNumber) {
                merMap.put(merchandiseId, number);
            } else {
                merMap.put(merchandiseId, merNumber.add(merNumber));
//				merMap.compute(merchandiseId, (key, value) -> value.add(number));
            }
        }

        //计算辅料原料
        List<LitemallOrderGoodsAccessory> orderGoodsAccessorys = litemallOrderGoodsAccessoryService.findByOrderGoodsId(litemallOrderGoods.getId());
        for (LitemallOrderGoodsAccessory orderGoodsAccessory : orderGoodsAccessorys) {
            Integer accessoryId = orderGoodsAccessory.getAccessoryId();
            LitemallGoodsAccessory accessory = litemallGoodsAccessoryService.findById(accessoryId);

            Integer merchandiseId = accessory.getMerchandiseId();
            //计算辅料原料的损耗量 = 份数 * 每份辅料原料的数量  * 损耗系数
            BigDecimal number = new BigDecimal(orderGoodsAccessory.getNumber() * accessory.getNumber());
            if (isConsumeRatio) {//计算消耗系数
                number = number.multiply(accessory.getConsumeRatio());
            }

            BigDecimal merNumber = merMap.get(merchandiseId);
            if (null == merNumber) {
                merMap.put(merchandiseId, number);
            } else {
                merMap.put(merchandiseId, merNumber.add(merNumber));
//				merMap.compute(merchandiseId, (key, value) -> value.add(number));
            }
        }
        return merMap;
    }

    /**
     * 配方
     * 订单配方
     *
     * @param orderId 订单id
     * @return {@link Response}<{@link OrderRecipeResponseVO}>
     */
    public Response<OrderRecipeResponseVO> recipe(Integer orderId) {
        LitemallOrder litemallOrder = orderService.findById(orderId);
        if (null == litemallOrder) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        OrderRecipeResponseVO response = new OrderRecipeResponseVO();
        BeanUtils.copyProperties(litemallOrder, response);

        List<OrderRecipeGoodsVO> result = new ArrayList<>();
        //查询订单商品
        List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
        if (!CollectionUtils.isEmpty(orderGoodsList)) {
            for (LitemallOrderGoods orderGoods : orderGoodsList) {
                OrderRecipeGoodsVO recipe = new OrderRecipeGoodsVO();
                BeanUtils.copyProperties(orderGoods, recipe);

                //查询规格辅料
                String[] specifications = orderGoods.getSpecifications();
                StringBuffer specAndAccessory = new StringBuffer(specifications[0]);
                //商品属性
                String property = getGoodsPropertyStr(orderGoods.getId());
                if (StringUtils.isNotBlank(property)) {
                    specAndAccessory.append("/").append(property);
                }
                String accessory = getGoodsAccessoryStr(orderGoods.getId());
                if (StringUtils.isNotBlank(accessory)) {
                    specAndAccessory.append("/").append(accessory);
                }
                recipe.setSpecAndAccessory(specAndAccessory.toString());

                List<OrderRecipeMerVO> merList = new ArrayList<>();
                Map<Integer, BigDecimal> merMap = caculateMerchandise(orderGoods, false);
                for (Integer merchandiseId : merMap.keySet()) {
                    OrderRecipeMerVO recipeMerVo = new OrderRecipeMerVO();

                    //查询原料信息
                    LitemallMerchandise litemallMerchandise = litemallMerchandiseService.findById(merchandiseId);
                    recipeMerVo.setMerchandiseId(merchandiseId);
                    recipeMerVo.setMerchandiseName(litemallMerchandise.getName());
                    recipeMerVo.setMerchandiseSn(litemallMerchandise.getMerchandiseSn());
                    recipeMerVo.setNumber(merMap.get(merchandiseId));
                    recipeMerVo.setUnit(litemallMerchandise.getBasicUnit());

                    merList.add(recipeMerVo);
                }
                recipe.setMerList(merList);
                result.add(recipe);
            }
        }

        response.setGoodsList(result);

        return ResponseUtil.ok(response);
    }

    /**
     * 重复
     * 重做
     *
     * @param shopId  商店id
     * @param request 请求
     * @return {@link Response}<{@link Object}>
     * @throws Exception 异常
     */
    @Transactional
    public Response<Object> repeat(Integer shopId, OrderRepeatRequestVO request) throws Exception {
        LitemallOrder originOrder = orderService.findById(request.getOrderId());
        if (null == originOrder) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        if (Constants.ORDER_STATUS_PICKUP != originOrder.getOrderStatus()) {
            //进行中的订单才能进行操作
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "不合法操作");
        }

        //创建订单
        LitemallOrder litemallOrder = new LitemallOrder();
        String orderSn = generateOrderSn();
        Integer maxSerialNo = orderService.getTodayMaxSerialNo(shopId);
        litemallOrder.setShopId(shopId);
        litemallOrder.setDeviceNo(request.getDeviceNo());
        litemallOrder.setOrderSn(orderSn);
        litemallOrder.setSerialNo(maxSerialNo + 1);
        litemallOrder.setOrderType(originOrder.getOrderType());//设置订单类型：1:堂食,2:外带
        litemallOrder.setOrderSource(Constants.ORDER_SOURCE_POS);//订单来源pos机
        litemallOrder.setOrderStatus(Constants.ORDER_STATUS_ONGOING);//订单状态--新建
        litemallOrder.setMadeStatus(Constants.ORDER_MADE_STATUS_NEW);//制作状态--待制作
        litemallOrder.setIsRepeat(true);
        litemallOrder.setOriginalSn(originOrder.getOrderSn());
        orderService.add(litemallOrder);

        Integer orderId = litemallOrder.getId();
        //创建订单商品
        List<OrderRepeatGoodsVO> goodsList = request.getGoodsList();
        for (OrderRepeatGoodsVO orderRepeatGoodsVo : goodsList) {
            LitemallOrderGoods originalGoods = orderGoodsService.findById(orderRepeatGoodsVo.getId());
            if (orderRepeatGoodsVo.getNumber() > originalGoods.getNumber()) {
                throw new RuntimeException("重做商品的数量超过原商品数量");
            }

            LitemallOrderGoods litemallOrderGoods = new LitemallOrderGoods();
            BeanUtils.copyProperties(originalGoods, litemallOrderGoods);
            litemallOrderGoods.setSellingPrice(BigDecimal.ZERO);
            litemallOrderGoods.setTaxPrice(BigDecimal.ZERO);
            litemallOrderGoods.setPrice(BigDecimal.ZERO);
            litemallOrderGoods.setNumber(orderRepeatGoodsVo.getNumber().shortValue());
            litemallOrderGoods.setOrderId(orderId);
            litemallOrderGoods.setMadeStatus(Constants.ORDER_GOODS_MADE_STATUS_NEW);
            orderGoodsService.add(litemallOrderGoods);

            //创建订单商品辅料
            Integer orderGoodsId = litemallOrderGoods.getId();
            List<LitemallOrderGoodsAccessory> originAccessorys = litemallOrderGoodsAccessoryService.findByOrderGoodsId(orderRepeatGoodsVo.getId());
            for (LitemallOrderGoodsAccessory originAccessory : originAccessorys) {
                LitemallOrderGoodsAccessory litemallOrderGoodsAccessory = new LitemallOrderGoodsAccessory();
                BeanUtils.copyProperties(originAccessory, litemallOrderGoodsAccessory);
                litemallOrderGoodsAccessory.setOrderGoodsId(orderGoodsId);
                litemallOrderGoodsAccessory.setOrderId(orderId);
                litemallOrderGoodsAccessory.setPrice(BigDecimal.ZERO);
                litemallOrderGoodsAccessoryService.add(litemallOrderGoodsAccessory);
            }
        }

        return ResponseUtil.ok();
    }

    /**
     * 支付成功
     *
     * @param shopId  商店id
     * @param userId  用户id
     * @param request 请求
     * @return {@link Response}<{@link Object}>
     */
    @Transactional
    public Response<Object> paidSuccess(Integer shopId, Integer userId, OrderPaidSuccessRequestVO request) {
        LitemallOrder order = orderService.findById(request.getOrderId());
        if (null == order) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        if (!order.getShopId().equals(shopId) ) {
            return ResponseUtil.fail(SHOP_INVALID_OPERATION, "当前店铺不能进行此操作");
        }
        if (Constants.ORDER_STATUS_UNPAID != order.getOrderStatus()) {
            //未支付订单才能进行操作
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "不合法操作");
        }

        Byte payType = request.getPayType();
        if (Constants.ORDER_PAY_TYPE_CLOVER == payType && StringUtils.isBlank(request.getOutTradeNo())) {
            //支付方式为clover支付时，外部交易订单id不可为空
            return ResponseUtil.fail(ORDER_OUT_TRADE_NO_IS_NULL, "当前支付方式的外部订单id不可为空");
        }

        order.setUserId(request.getMemberId());//设置会员id
        order.setCurrency(DefaultCurType.CAD.getType());
        order.setPayTime(LocalDateTime.now());
        order.setPayType(payType);
        order.setPayId(request.getPayId());
        order.setOutTradeNo(request.getOutTradeNo());
        order.setOrderStatus(Constants.ORDER_STATUS_ONGOING);//订单状态修改为“进行中”
        order.setMadeStatus(Constants.ORDER_MADE_STATUS_NEW);//制作状态为“待制作”
        orderService.updateById(order);

        BigDecimal actualPrice = order.getActualPrice();
        //现金支付的话
        if (Constants.ORDER_PAY_TYPE_CASH == payType) {
            //保存现金支付记录
            LitemallOrderCash cash = new LitemallOrderCash();
            cash.setOrderId(order.getId());
            actualPrice = canadaRoundup(actualPrice);
            cash.setOrderPrice(actualPrice);
            cash.setCash(request.getActualPayAmount());
            cash.setChange(request.getActualPayAmount().subtract(actualPrice));
            cash.setAddUserId(userId);
            cash.setAddUserName(litemallUserService.findById(userId).getUsername());
            litemallOrderCashService.add(cash);
        }

        LitemallOrderVO vo = new LitemallOrderVO();
        BeanUtils.copyProperties(order, vo);
//		 vo = getOrderGoodsVos(vo,order.getId(),shopId);

        //支付成功则记账
        addAccountBook(order.getShopId(), actualPrice, "pos order", 0, Constants.BOOK_SOURCE_TYPE_ORDER);

        Integer paidNum = orderService.queryPaid(shopId, userId);
//		pushService.pushMsgToShop(paidNum.toString(),order.getShopId());
        noticeHelper.noticeUser(MESSAGE_TYPE_PAY,"来了个新订单", userId,JSON.toJSONString(order.getId()));
        return ResponseUtil.ok();
    }

    /**
     * 余额支付
     *
     * @param shopId  商店id
     * @param userId  用户id
     * @param request 请求
     * @return {@link Response}<{@link Object}>
     */
    @Transactional
    public Response<Object> balancePay(Integer shopId, Integer userId, OrderBalancePayRequestVO request) {
        LitemallOrder order = orderService.findById(request.getOrderId());
        if (null == order) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        if (!order.getShopId().equals(shopId)) {
            return ResponseUtil.fail(SHOP_INVALID_OPERATION, "当前店铺不能进行此操作");
        }

        //判断门店状态
        Response<Object> error = validShop(order.getShopId());
        if (error != null) {
            return error;
        }

        // 检查这个订单是否已经处理过
        if (OrderStatusUtil.isPayStatus(order) || order.getPayId() != null) {
            return ResponseUtil.fail(ORDER_PAY_FAIL, order.getOrderSn() + "订单已经处理成功!");
        }

        if (Constants.ORDER_STATUS_UNPAID != order.getOrderStatus()) {
            //未支付订单才能进行操作
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "不合法操作");
        }

        LitemallUser member = litemallUserService.findById(request.getMemberId());
        if (member == null) {
            return ResponseUtil.badArgument(ORDER_PAY_IS_NULL_MERMEBR, "会员不存在");
        }
        if (member.getAvailableAmount().compareTo(order.getActualPrice()) < 0) {
            return ResponseUtil.badArgument(ORDER_PAY_NOT_ENOUGH_AMOUNT, "余额不足");
        }


        //记录余额支付情况
        LitemallRechargeConsumption log = new LitemallRechargeConsumption();
        log.setAmount(order.getActualPrice());
        log.setAddUserId(userId);
        log.setOrderId(order.getId());
        log.setUserId(member.getId());
        log.setUsername(member.getUsername());
        log.setMobile(member.getMobile());
        log.setPoints(member.getPoints());
        log.setType(Constants.LOG_GIFTCARD_CONSUME);
        log.setUserLevel(member.getUserLevel());
        log.setAvailableAmount(member.getAvailableAmount().subtract(order.getActualPrice()));
        log.setOrderSource(ORDER_SOURCE_POS);
        litemallRechargeConsumptionService.add(log);

        //修改订单状态
        order.setUserId(request.getMemberId());//设置会员id
        order.setCurrency(DefaultCurType.CAD.getType());
        order.setPayTime(LocalDateTime.now());
        order.setPayType(Constants.ORDER_PAY_TYPE_BALANCE);
        order.setOrderStatus(Constants.ORDER_STATUS_ONGOING);//订单状态修改为“进行中”
        order.setMadeStatus(Constants.ORDER_MADE_STATUS_NEW);//制作状态为“待制作”
        order.setPayId(String.valueOf(log.getId()));        //将消费日志id作为支付id
        order.setTransationId(String.valueOf(log.getId())); //将消费日志id作为transation id
        order.setPayTime(LocalDateTime.now());
        order.setMemberId(member.getId());
        orderService.updateById(order);

        //赠送积分
        paypalService.presentPoint(order.getId(),log.getId());
        //更新用户余额
        LitemallUser update = new LitemallUser();
        update.setId(member.getId());
        update.setAvailableAmount(member.getAvailableAmount().subtract(order.getActualPrice()));
        litemallUserService.updateById(update);

        LitemallOrderVO vo = new LitemallOrderVO();
        BeanUtils.copyProperties(order, vo);
//		vo = getOrderGoodsVos(vo,order.getId(),shopId);

        //支付成功则记账
        addAccountBook(order.getShopId(), order.getActualPrice(), "pos order", 0, Constants.BOOK_SOURCE_TYPE_ORDER);

        Integer paidNum = orderService.queryPaid(shopId, userId);
//		pushService.pushMsgToShop(paidNum.toString(),order.getShopId());
        noticeHelper.noticeUser(MESSAGE_TYPE_PAY,"来了个新订单", userId,JSON.toJSONString(order.getId()));
//        noticeHelper.noticeShop(MESSAGE_TYPE_PAY, JSON.toJSONString(order.getId()), shopId);
        return ResponseUtil.ok();
    }

    /**
     * 礼品卡支付
     * 礼物卡支付
     *
     * @param shopId  商店id
     * @param userId  用户id
     * @param request 请求
     * @return {@link Response}<{@link Object}>
     */
    @Transactional
    public Response<Object> giftCardPay(Integer shopId, Integer userId, OrderCardPayRequestVO request) {
        LitemallOrder order = orderService.findById(request.getOrderId());
        if (null == order) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        if (!order.getShopId().equals(shopId)) {
            return ResponseUtil.fail(SHOP_INVALID_OPERATION, "当前店铺不能进行此操作");
        }

        //判断门店状态
        Response<Object> error = validShop(order.getShopId());
        if (error != null) {
            return error;
        }

        // 检查这个订单是否已经处理过
        if (OrderStatusUtil.isPayStatus(order) || order.getPayId() != null) {
            return ResponseUtil.fail(ORDER_PAY_FAIL, order.getOrderSn() + "订单已经处理成功!");
        }

        if (Constants.ORDER_STATUS_UNPAID != order.getOrderStatus()) {
            //未支付订单才能进行操作
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "不合法操作");
        }

        LitemallGiftCardUser card = litemallGiftCardUserService.findById(request.getCardId());
        if (card == null) {
            return ResponseUtil.badArgument(ORDER_PAY_IS_NULL_CARD, "礼物卡不存在");
        }
        if (card.getAmount().compareTo(order.getActualPrice()) < 0) {
            return ResponseUtil.badArgument(ORDER_PAY_NOT_ENOUGH_AMOUNT, "余额不足");
        }
        //更新卡余额
        LitemallGiftCardUser giftCard = new LitemallGiftCardUser();
        giftCard.setAmount(card.getAmount().subtract(order.getActualPrice()));
        giftCard.setId(card.getId());
        if (litemallGiftCardUserService.updateWithOptimisticLocker(giftCard, card.getUpdateTime()) == 0) {
            return ResponseUtil.updatedDateExpired();
        }

        //记录消费情况
        LitemallGiftCardUserLog log = new LitemallGiftCardUserLog();
        log.setOrderId(order.getId());
        log.setAmount(order.getActualPrice());
        log.setAddUserId(card.getUserId());
        log.setType(Constants.LOG_GIFTCARD_CONSUME);
        log.setCardNumber(card.getCardNumber());
        log.setCardUserId(card.getId());
        log.setContent("pos gift card payment");
        log.setOrderSource(Constants.ORDER_SOURCE_POS);
        log.setBalance(card.getAmount());
        //赠送积分
        BigDecimal point =  paypalService.presentPoint(order.getId(),null);
        log.setChangePoints(point);
        log.setAddTime(LocalDateTime.now());
        log.setUpdateTime(LocalDateTime.now());
        litemallGiftCardUserLogService.save(log);

        //修改订单状态
        order.setCurrency(DefaultCurType.CAD.getType());
        order.setPayTime(LocalDateTime.now());
        order.setPayType(Constants.ORDER_PAY_TYPE_CARD);
        order.setOrderStatus(Constants.ORDER_STATUS_ONGOING);//订单状态修改为“进行中”
        order.setMadeStatus(Constants.ORDER_MADE_STATUS_NEW);//制作状态为“待制作”
        order.setPayId(String.valueOf(log.getId()));        //将消费日志id作为支付id
        order.setTransationId(String.valueOf(log.getId())); //将消费日志id作为transation id
        order.setPayTime(LocalDateTime.now());
        order.setMemberId(giftCard.getUserId());
        order.setUserId(card.getUserId());
        order.setShopId(shopId);
        orderService.updateById(order);

        LitemallOrderVO vo = new LitemallOrderVO();
        BeanUtils.copyProperties(order, vo);
//		vo = getOrderGoodsVos(vo,order.getId(),shopId);

        //支付成功则记账
        addAccountBook(order.getShopId(), order.getActualPrice(), "pos order", 0, Constants.BOOK_SOURCE_TYPE_ORDER);
        noticeHelper.noticeUser(MESSAGE_TYPE_PAY,"A new order came in", userId,JSON.toJSONString(order.getId()));
        return ResponseUtil.ok();
    }

    /**
     * 计算结算
     *
     * @param userId   用户id
     * @param deviceNo 设备没有
     * @return {@link OrderCalculateSettlementResponseVO}
     */
    public OrderCalculateSettlementResponseVO calculateSettlement(Integer userId, String deviceNo) {
        OrderCalculateSettlementResponseVO response = new OrderCalculateSettlementResponseVO();
        //查询上次机器的交接记录
        LocalDateTime minTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LitemallSettlement settlement = litemallSettlementService.getLatest(deviceNo);
        if (settlement != null) {
            minTime = settlement.getAddTime();
        }

        BigDecimal amount = BigDecimal.ZERO;
        List<LitemallOrderCash> result = litemallOrderCashService.queryAfterTimeByUserId(userId, minTime);
        if (!CollectionUtils.isEmpty(result)) {
            for (LitemallOrderCash litemallOrderCash : result) {
                amount = amount.add(litemallOrderCash.getOrderPrice());
            }
        }

        //计算优惠券金额
        BigDecimal couponPrice = BigDecimal.ZERO;
        if(CollectionUtils.isEmpty(result)){

            for (LitemallOrderCash litemallOrderCash : result) {
                LitemallOrder order = orderService.findById(litemallOrderCash.getOrderId());
                couponPrice = couponPrice.add(order.getCouponPrice() != null ? order.getCouponPrice() : BigDecimal.ZERO);
            }
        }



        response.setOrderAmount(amount);

        //查询现金退款的金额
        BigDecimal refundAmount = BigDecimal.ZERO;
        List<LitemallRefund> refundList = litemallRefundService.queryAfterTimeByUserIdAndRefundType(userId, minTime, Constants.ORDER_PAY_TYPE_CASH);
        if (!CollectionUtils.isEmpty(refundList)) {
            for (LitemallRefund litemallRefund : refundList) {
                refundAmount = refundAmount.add(litemallRefund.getActualPrice());
            }
        }


        response.setRefundAmount(refundAmount);
        response.setReceivableAmount(amount.subtract(refundAmount));
        return response;
    }

    /**
     * 计算退款
     * 退款计算
     *
     * @param request 请求
     * @return {@link Response}<{@link OrderCalculateRefundResponseVO}>
     */
    public Response<OrderCalculateRefundResponseVO> calculateRefund(OrderCalculateRefundRequestVO request) {
        OrderCalculateRefundResponseVO response = new OrderCalculateRefundResponseVO();

        Integer orderId = request.getOrderId();
        LitemallOrder order = orderService.findById(orderId);
        if (null == order) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        Short orderStatus = order.getOrderStatus();
        Byte madeStatus = order.getMadeStatus();
        if (!(Constants.ORDER_STATUS_ONGOING.equals(orderStatus))) {
            return ResponseUtil.fail(ORDER_INVALID_REFUND, "只有待制作、已取餐或已完成的订单才能退款");
        }

        //查询订单商品
        List<OrderRefundGoodsVO> goods = request.getGoods();
        BigDecimal goodsPrice = BigDecimal.ZERO;
        BigDecimal taxPrice = BigDecimal.ZERO;
        BigDecimal totalPrice = BigDecimal.ZERO;
        boolean firstFlag = false;
        for (OrderRefundGoodsVO orderCalculateRefundGoodsVo : goods) {
            Integer orderGoodsId = orderCalculateRefundGoodsVo.getOrderGoodsId();

            LitemallOrderGoods orderGoods = orderGoodsService.findById(orderGoodsId);
            if (null == orderGoods) {
                return ResponseUtil.fail(ORDER_GOODS_UNKNOWN, "订单商品不存在");
            }

            if(firstFlag == false && orderGoods.getRefundNumber() != null && orderGoods.getRefundNumber() >0){
                firstFlag = true;
            }

            Integer refundNumber = orderCalculateRefundGoodsVo.getRefundNumber();
            if (refundNumber <= 0) {
                return ResponseUtil.fail(ORDER_REFUND_GOODS_NUMBER_INVALID, "商品的退款数量必须大于0");
            }
            Integer canRefundNumber = orderGoods.getNumber() - orderGoods.getRefundNumber();
            if (canRefundNumber < refundNumber) {
                return ResponseUtil.fail(ORDER_REFUND_NUMBER_INVALID, "退款商品数量超过可退数量");
            }
            BigDecimal refundGoodsPrice = BigDecimal.ZERO;
            if (orderGoods.getDiscountPrice().compareTo(new BigDecimal(0.0)) <= 0) {

                 refundGoodsPrice = orderGoods.getSellingPrice().multiply(new BigDecimal(refundNumber));
            }else{
                refundGoodsPrice = orderGoods.getDiscountPrice().multiply(new BigDecimal(refundNumber));
            }

            BigDecimal refundTaxPrice = BigDecimal.ZERO;
            //创建退款税费
//            List<LitemallOrderTax> orderTaxs = litemallOrderTaxService.queryByOrderIdAndOrderGoodsId(orderId, orderGoodsId);
            if(orderGoods.getTaxPrice().compareTo(BigDecimal.ZERO) == 0 || orderGoods.getTaxPrice()== null){
                refundTaxPrice = BigDecimal.ZERO;
            }else{
                refundTaxPrice = orderGoods.getTaxPrice().multiply(new BigDecimal(refundNumber)).divide(new BigDecimal(orderGoods.getNumber()),2, BigDecimal.ROUND_HALF_UP);
            }
//            refundTaxPrice = orderGoods.getTaxPrice().multiply(new BigDecimal(refundNumber)).divide(new BigDecimal(orderGoods.getNumber())).setScale(2, BigDecimal.ROUND_HALF_UP);
            goodsPrice = goodsPrice.add(orderGoods.getSellingPrice().multiply(new BigDecimal(refundNumber)));
            taxPrice = taxPrice.add(refundTaxPrice);
        }

        LumiereCloverPayLog log = lumiereCloverPayLogService.queryByOrderId(String.valueOf(orderId));


        totalPrice = goodsPrice.add(taxPrice);

        if(order.getCouponPrice() != null && firstFlag == false){
            totalPrice = totalPrice.subtract(order.getCouponPrice()).compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : totalPrice.subtract(order.getCouponPrice());
        }
        response.setRefundType(order.getPayType());
        response.setGoodsPrice(goodsPrice);
        response.setTaxPrice(taxPrice);
        response.setTotalPrice(totalPrice);
        response.setActualPrice(order.getPayType().equals(PAY_TYPE_CASH) == true ? canadaRoundup(totalPrice) : totalPrice);
        response.setExternalId(log == null ? null : log.getExternalId());
        response.setOrderId(log == null ? null : log.getOrderId());
        response.setPaymentId(log == null ? null : log.getPaymentId());
        return ResponseUtil.ok(response);
    }

    /**
     * 退款
     *
     * @param shopId  商店id
     * @param userId  用户id
     * @param request 请求
     * @return {@link Response}<{@link Integer}>
     */
    @Transactional
    public Response<Integer> refund(Integer shopId, Integer userId, OrderRefundRequestVO request) {
        Integer orderId = request.getOrderId();
        LitemallOrder order = orderService.findById(orderId);
        if (null == order) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        Short orderStatus = order.getOrderStatus();
        Byte madeStatus = order.getMadeStatus();
        if (!(Constants.ORDER_STATUS_ONGOING.equals(orderStatus))) {
            return ResponseUtil.fail(ORDER_INVALID_REFUND, "只有待制作、已取餐或已完成的订单才能退款");
        }

        //clover支付退款
//        if (Constants.ORDER_PAY_TYPE_CLOVER == order.getPayType()) {
//            //request
//            String outRefundId = request.getOutRefundId();
//            if (StringUtils.isBlank(outRefundId)) {//外部退款id为空
//                return ResponseUtil.fail(ORDER_REFUND_OUT_TRAND_ID_IS_NULL, "clover外部退款id为空");
//            }
//
//            LitemallRefund litemallRefund = litemallRefundService.queryByOutRefundId(outRefundId);
//            if (litemallRefund != null) {
//                return ResponseUtil.fail(ORDER_REFUND_EXIST, "该退款订单已存在");
//            }
//        }

        List<OrderRefundGoodsVO> goods = request.getGoods();
        List<Pair<LitemallOrderGoods, Integer>> orderGoodsLs = new ArrayList<>();
        for (OrderRefundGoodsVO orderCalculateRefundGoodsVo : goods) {
            Integer orderGoodsId = orderCalculateRefundGoodsVo.getOrderGoodsId();
            LitemallOrderGoods orderGoods = orderGoodsService.findById(orderGoodsId);

            if (null == orderGoods) {
                return ResponseUtil.fail(ORDER_GOODS_UNKNOWN, "订单商品不存在");
            }

            Integer refundNumber = orderCalculateRefundGoodsVo.getRefundNumber();
            if (refundNumber <= 0) {
                return ResponseUtil.fail(ORDER_REFUND_GOODS_NUMBER_INVALID, "商品的退款数量必须大于0");
            }
            Integer canRefundNumber = orderGoods.getNumber() - orderGoods.getRefundNumber();
            if (canRefundNumber < refundNumber) {
                return ResponseUtil.fail(ORDER_REFUND_NUMBER_INVALID, "退款商品数量超过可退数量");
            }


            Pair<LitemallOrderGoods, Integer> pair = Pair.of(orderGoods, refundNumber);
            orderGoodsLs.add(pair);
        }

        //退款
        Integer refundId = refund(shopId, userId, request.getDeviceNo(), request.getOutRefundId(), order, orderGoodsLs);
        //订单获取积分从用户账户扣减
        if(order.getPayType() != Constants.PAY_TYPE_POINT_EXCHANGE.byteValue()){
            BigDecimal points =   order.getPoints();
            LitemallUser user = litemallUserService.findById(order.getUserId());

            if(points != null){
                if(points.compareTo(user.getPoints()) > 0){
                    return ResponseUtil.fail(111,"当前积分不足以匹配用户购买时赠送的积分,退款失败");
                }else{
                    user.setPoints(user.getPoints().subtract(points));
                    litemallUserService.updateById(user);

                    LitemallIntegralLog log = new LitemallIntegralLog();
                    log.setUserId(user.getId());
                    log.setType(INTEGRAL_LOG_TYPE_RETURN);
                    log.setOrderId(order.getId());
                    log.setPoints(user.getPoints());
                    log.setChangePoints(BigDecimal.ZERO.subtract(points));
                    //添加详细信息
                    log.setUseType(7);
                    log.setGoodsName(orderGoodsService.queryByOid(order.getId()).stream().map(litemallOrderGoods -> litemallOrderGoods.getGoodsName()).collect(Collectors.toList()));
                    integralLogService.add(log);
                }
            }
        }

//		noticeHelper.noticeShop(MESSAGE_TYPE_PAY, JSON.toJSONString(vo), order.getShopId());

        return ResponseUtil.ok(refundId);
    }

    /**
     * 退还所有
     * 全部退款
     *
     * @param shopId  商店id
     * @param userId  用户id
     * @param request 请求
     * @return {@link Response}<{@link Integer}>
     */
    @Transactional
    public Response<Integer> refundAll(Integer shopId, Integer userId, OrderRefundAllRequestVO request) {
        Integer orderId = request.getOrderId();
        LitemallOrder order = orderService.findById(orderId);
        if (null == order) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        Short orderStatus = order.getOrderStatus();
        Byte madeStatus = order.getMadeStatus();
        if (!(Constants.ORDER_STATUS_ONGOING.equals(orderStatus))) {
            return ResponseUtil.fail(ORDER_INVALID_REFUND, "只有待制作、已取餐或已完成的订单才能退款");
        }

        //clover支付退款
        if (Constants.ORDER_PAY_TYPE_CLOVER == order.getPayType()) {
            //request
            String outRefundId = request.getOutRefundId();
            if (StringUtils.isBlank(outRefundId)) {//外部退款id为空
                return ResponseUtil.fail(ORDER_REFUND_OUT_TRAND_ID_IS_NULL, "clover外部退款id为空");
            }

            LitemallRefund litemallRefund = litemallRefundService.queryByOutRefundId(outRefundId);
            if (litemallRefund != null) {
                return ResponseUtil.fail(ORDER_REFUND_EXIST, "该退款订单已存在");
            }
        }

        List<LitemallOrderGoods> orderGoodsLs = orderGoodsService.queryByOid(orderId);
        List<Pair<LitemallOrderGoods, Integer>> goods = new ArrayList<>();
        for (LitemallOrderGoods orderGoods : orderGoodsLs) {
            Integer canRefundNumber = orderGoods.getNumber() - orderGoods.getRefundNumber();
            if (canRefundNumber > 0) {
                Pair<LitemallOrderGoods, Integer> pair = Pair.of(orderGoods, canRefundNumber);
                goods.add(pair);
            }
        }

        if (!CollectionUtils.isEmpty(goods)) {
            //退款
            Integer refundId = refund(shopId, userId, request.getDeviceNo(), request.getOutRefundId(), order, goods);
            //订单获取积分从用户账户扣减
            if(order.getPayType() != Constants.PAY_TYPE_POINT_EXCHANGE.byteValue()){
                BigDecimal points =   order.getPoints();
                LitemallUser user = litemallUserService.findById(order.getUserId());

                if(points != null){
                    if(points.compareTo(user.getPoints()) > 0){
                        return ResponseUtil.fail(111,"当前积分不足以匹配用户购买时赠送的积分,退款失败");
                    }else{
                        user.setPoints(user.getPoints().subtract(points));
                        litemallUserService.updateById(user);

                        LitemallIntegralLog log = new LitemallIntegralLog();
                        log.setUserId(user.getId());
                        log.setType(INTEGRAL_LOG_TYPE_RETURN);
                        log.setOrderId(order.getId());
                        log.setPoints(user.getPoints());
                        log.setChangePoints(BigDecimal.ZERO.subtract(points));
                        integralLogService.add(log);
                    }
                }
            }
            return ResponseUtil.ok(refundId);
        } else {
            return ResponseUtil.fail(ORDER_REFUND_NO_NUMBER, "订单无可退款的商品");
        }


    }

    /**
     * 退款
     *
     * @param shopId      操作店铺id
     * @param goods       <退款订单商品,退款数量>集合
     * @param userId      用户id
     * @param deviceNo    设备没有
     * @param outRefundId 了退款id
     * @param order       订单
     * @return {@link Integer}
     */
    private Integer refund(Integer shopId, Integer userId, String deviceNo, String outRefundId, LitemallOrder order, List<Pair<LitemallOrderGoods, Integer>> goods) {
        Integer orderId = order.getId();

        //创建退款
        LitemallRefund refund = new LitemallRefund();
        refund.setOrderId(orderId);
        refund.setOrderShopId(order.getShopId());
        refund.setRefundShopId(shopId);
        refund.setOrderSn(order.getOrderSn());
        refund.setRefundSn(generateRefundSn());
        refund.setUserId(order.getUserId());

        if (outRefundId != null && outRefundId != "") {
            refund.setOutRefundId(outRefundId);
        } else {
            refund.setOutRefundId(null);
        }
        refund.setDeviceNo(deviceNo);
        Byte payType = order.getPayType();
        refund.setRefundType(payType);
        refund.setRefundState(Constants.REFUND_STATUS_ONGOING);//退款中
        refund.setAddUserId(userId);
        litemallRefundService.add(refund);

        Integer refundId = refund.getId();
        //查询订单商品
        BigDecimal goodsPrice = BigDecimal.ZERO;
        BigDecimal taxPrice = BigDecimal.ZERO;
        BigDecimal totalPrice = BigDecimal.ZERO;
        Integer canOrderRefundNumber = 0;
        List<Integer> refundOrderGoodsIds = new ArrayList<>();
        boolean firstFlag = false;

        //记录退款商品名称
        List refundGoodsNames = CollUtil.newArrayList();
        for (Pair<LitemallOrderGoods, Integer> pair : goods) {
            LitemallOrderGoods orderGoods = pair.getLeft();
            refundGoodsNames.add(orderGoods.getGoodsName());
            if(firstFlag == false && orderGoods.getRefundNumber() != null && orderGoods.getRefundNumber() > 0){
                firstFlag = true;
            }
            Integer refundNumber = pair.getRight();
            Integer orderGoodsId = orderGoods.getId();
            refundOrderGoodsIds.add(orderGoodsId);
            //更新订单商品的总退款数量
            Integer totalRefundNumber = orderGoods.getRefundNumber() + refundNumber;
            Integer lastRefundNumber = orderGoods.getNumber() - totalRefundNumber;
            //计算订单的可退款商品的数量
            canOrderRefundNumber = canOrderRefundNumber + lastRefundNumber;

            //如果商品的可退款数量为0，且订单为待制作状态，则订单商品的制作状态修改为制作完成
            if (Constants.ORDER_STATUS_ONGOING.equals(order.getOrderStatus())
                    && Constants.ORDER_MADE_STATUS_NEW.equals(order.getMadeStatus()) && lastRefundNumber == 0) {
                orderGoods.setMadeStatus(Constants.ORDER_GOODS_MADE_STATUS_NEW);
            }
            orderGoods.setRefundNumber(totalRefundNumber.shortValue());
            LitemallShop shop = shopService.findById(shopId);
            //添加退款时间 退款门店
            if(orderGoods.getRefundTime()==null){
                Map map = new HashMap();
                map.put(shop.getName(),LocalDateTime.now().toString());
                orderGoods.setRefundTime(Arrays.asList(map));
            }else {
                Map map = new HashMap();
                map.put(shop.getName(),LocalDateTime.now().toString());
                orderGoods.getRefundTime().add(map);
            }
            orderGoodsService.updateById(orderGoods);

            //创建退款商品
            LitemallRefundGoods refundGoods = new LitemallRefundGoods();
            refundGoods.setRefundId(refundId);
            refundGoods.setOrderId(orderId);
            refundGoods.setOrderGoodsId(orderGoodsId);
            refundGoods.setGoodsId(orderGoods.getGoodsId());
            refundGoods.setNumber(refundNumber.shortValue());
            refundGoods.setUnitPrice(orderGoods.getUnitPrice());
            BigDecimal discountPrice = orderGoods.getDiscountPrice().compareTo(BigDecimal.ZERO) > 0 ? orderGoods.getDiscountPrice() : orderGoods.getSellingPrice();
            BigDecimal refundGoodsPrice = discountPrice.multiply(new BigDecimal(refundNumber));
            refundGoods.setGoodsPrice(refundGoodsPrice);
            litemallRefundGoodsService.add(refundGoods);
            Integer refundGoodsId = refundGoods.getId();

            //创建退款税费
            BigDecimal refundTaxPrice = BigDecimal.ZERO;
            List<LitemallOrderTax> orderTaxs = litemallOrderTaxService.queryByOrderIdAndOrderGoodsId(orderId, orderGoodsId);
            if (!CollectionUtils.isEmpty(orderTaxs)) {
                for (LitemallOrderTax orderTax : orderTaxs) {
                    LitemallRefundTax refundTax = new LitemallRefundTax();
                    refundTax.setRefundId(refundId);
                    refundTax.setRefundGoodsId(refundGoodsId);
                    refundTax.setCode(orderTax.getCode());
                    BigDecimal value = orderTax.getValue();
                    refundTax.setValue(value);
                    //计算code为GST或其他的税费是多少
                    BigDecimal price = refundGoodsPrice.multiply(value).divide(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP);
                    refundTax.setPrice(price);
                    litemallRefundTaxService.add(refundTax);

                    refundTaxPrice = refundTaxPrice.add(price);
                }
            }

            //修改退款商品的税费
            refundGoods.setTaxPrice(refundTaxPrice);
            refundGoods.setPrice(refundGoodsPrice.add(refundTaxPrice));
            litemallRefundGoodsService.update(refundGoods);

            goodsPrice = goodsPrice.add(refundGoodsPrice);
            taxPrice = taxPrice.add(refundTaxPrice);
        }
        totalPrice = goodsPrice.add(taxPrice);
        //实际支付金额
        BigDecimal actualPrice = totalPrice;

        //判断是否是第一次退款

       if(order.getCouponPrice() != null && firstFlag == false){
           actualPrice = actualPrice.subtract(order.getCouponPrice()).compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : actualPrice.subtract(order.getCouponPrice());
       }

        if (Constants.ORDER_PAY_TYPE_CARD == payType) {//礼物卡支付
            //礼物卡退款
            giftCardRefund(userId, Integer.valueOf(order.getPayId()), refundId, actualPrice);
            order.setRefundStatus(Constants.ORDER_REFUND_STATUS_SUCCESS);
            refund.setRefundState(Constants.REFUND_STATUS_SUCCESS);//退款成功
            //退款成功则记账
            addAccountBook(order.getShopId(), actualPrice, "Gift card payment refunds", 1, Constants.BOOK_SOURCE_TYPE_REFUND);
        } else if (Constants.ORDER_PAY_TYPE_BALANCE == payType) {//余额支付
            //余额退款
            balancePayRefund(userId, order.getUserId(), refundId, actualPrice);
            order.setRefundStatus(Constants.ORDER_REFUND_STATUS_SUCCESS);
            refund.setRefundState(Constants.REFUND_STATUS_SUCCESS);//退款成功
            //退款成功则记账
            addAccountBook(order.getShopId(), actualPrice, "Balance payment refund", 1, Constants.BOOK_SOURCE_TYPE_REFUND);
        } else if (Constants.ORDER_PAY_TYPE_CASH == payType) {//现金支付
            //现金四舍五入
            actualPrice = canadaRoundup(totalPrice);
            order.setRefundStatus(Constants.ORDER_REFUND_STATUS_SUCCESS);
            refund.setRefundState(Constants.REFUND_STATUS_SUCCESS);//退款成功
            //记录现金交易
            LitemallCashSchedule cashSchedule = LitemallCashSchedule.builder()
                    .userId(userId)
                    .shopId(shopId)
                    .type(1)
                    .payTime(LocalDateTime.now())
                    .orderCash(order.getActualPrice())
                    .receiveCash(BigDecimal.ZERO)
                    .change(BigDecimal.ZERO)
                    .actualCash(BigDecimal.ZERO)
                    .refundCash(order.getActualPrice())
                    .deviceNo(deviceNo)
                    .build();
            litemallCashScheduleService.save(cashSchedule);
            //退款成功则记账
            addAccountBook(shopId, actualPrice, "Cash refund", 1, Constants.BOOK_SOURCE_TYPE_REFUND);
        }
//        else if (Constants.ORDER_PAY_TYPE_CLOVER == payType) {//clover支付
//            //TODO clover退款
//            order.setRefundStatus(Constants.ORDER_REFUND_STATUS_SUCCESS);
//            refund.setRefundState(Constants.REFUND_STATUS_SUCCESS);//退款成功
//            //退款成功则记账
//            addAccountBook(order.getShopId(), actualPrice, "线上退款", 1, Constants.BOOK_SOURCE_TYPE_REFUND);
//        }

        //更新退款金额
        refund.setGoodsPrice(goodsPrice);
        refund.setTaxPrice(taxPrice);
        refund.setPrice(totalPrice);
        refund.setActualPrice(actualPrice);
        litemallRefundService.update(refund);


        //未退款的订单商品已经全部退款
       List<LitemallOrderGoods> ogs =  orderGoodsService.queryByOrderIdAndOrderGoodsId(orderId,refundOrderGoodsIds);;
        for (int i = 0; i < ogs.size(); i++) {
            canOrderRefundNumber += ogs.get(i).getNumber() - ogs.get(i).getRefundNumber();
        }

        if (canOrderRefundNumber == 0) {
            //待制作状态的订单全部退款，则将订单状态设置为退款完成
            if (Constants.ORDER_STATUS_ONGOING.equals(order.getOrderStatus())
                    && (Constants.ORDER_MADE_STATUS_NEW.equals(order.getMadeStatus()))) {
                order.setOrderStatus(Constants.STATUS_REFUND_CONFIRM);
            }

            if (Constants.ORDER_PAY_TYPE_CASH == payType
                    || Constants.ORDER_PAY_TYPE_BALANCE == payType
                    || Constants.ORDER_PAY_TYPE_CARD == payType) {
                //设置退款成功
                order.setRefundStatus(Constants.ORDER_REFUND_STATUS_SUCCESS);
            }
            //更新订单是否退款字段
            order.setIsRefund(true);
            order.setMadeStatus((byte) -1);
            orderService.updateById(order);
        }





        //发送系统助手通知
        noticeHelper.noticeUser(Constants.MSG_TYPE_ORDER, LiteamllWebConstants.WEB_ORDER_REFUND_TITLE_NOTICEHELPER,
                String.format(LiteamllWebConstants.WEB_ORDER_REFUND_NOTICEHELPER,order.getOrderSn(),refundGoodsNames.toString()),order.getMemberId(),order);
        return refundId;

    }

    /**
     * 添加帐
     * 记账功能
     *
     * @param shopId      商店id
     * @param actualPrice 实际价格
     * @param remark      备注
     * @param recordType  记录类型
     * @param sourceType  源类型
     */
    private void addAccountBook(Integer shopId, BigDecimal actualPrice, String remark, Integer recordType, Integer sourceType) {
        LitemallAccountBookFormDto form = new LitemallAccountBookFormDto();
        form.setShopId(shopId);
        form.setRecordType(recordType);
        form.setRecordDate(LocalDateTime.now());
        form.setAmount(actualPrice);
        form.setRemark(remark);
        form.setSourceType(sourceType);
        litemallAccountBookService.create(shopId, form);
    }

    /**
     * 加拿大综述
     * 加拿大四舍五入
     *
     * @param price 价格
     * @return {@link BigDecimal}
     */
    public BigDecimal canadaRoundup(BigDecimal price) {
        BigDecimal a = price.multiply(BigDecimal.TEN).setScale(1, BigDecimal.ROUND_HALF_UP);
        BigDecimal b = a.remainder(BigDecimal.ONE);
        if (b.compareTo(new BigDecimal(0.2).setScale(1, BigDecimal.ROUND_HALF_UP)) <= 0) {
            a = a.subtract(b);
        } else if (b.compareTo(new BigDecimal(0.7).setScale(1, BigDecimal.ROUND_HALF_UP)) <= 0) {
            a = a.subtract(b).add(new BigDecimal(0.5));
        } else {
            a = a.subtract(b).add(new BigDecimal(1));
        }

        a = a.divide(BigDecimal.TEN).setScale(2, BigDecimal.ROUND_HALF_UP);
        return a;
    }

    /**
     * 余额支付退款
     *
     * @param userId   用户id
     * @param memberId 成员身份
     * @param refundId 退款id
     * @param price    价格
     */
    private void balancePayRefund(Integer userId, Integer memberId, Integer refundId, BigDecimal price) {
        LitemallUser member = litemallUserService.findById(memberId);
        //记录余额支付情况
        LitemallRechargeConsumption log = new LitemallRechargeConsumption();
        log.setAmount(price);
        log.setAddUserId(userId);
        log.setOrderId(refundId);
        log.setUserId(member.getId());
        log.setUsername(member.getUsername());
        log.setMobile(member.getMobile());
//        log.setPoints(member.getPoints());
        log.setType(Constants.LOG_GIFTCARD_REFUND);
        log.setUserLevel(member.getUserLevel());
        log.setAvailableAmount(member.getAvailableAmount().add(price));
        log.setOrderSource(Constants.ORDER_SOURCE_POS);
        litemallRechargeConsumptionService.add(log);

        //更新用户余额
        LitemallUser update = new LitemallUser();
        update.setId(member.getId());
        update.setAvailableAmount(member.getAvailableAmount().add(price));
        litemallUserService.updateById(update);
    }

    /**
     * 礼品卡退款
     * 礼物卡退款
     *
     * @param userId   用户id
     * @param payId    支付id
     * @param refundId 退款id
     * @param price    价格
     */
    private void giftCardRefund(Integer userId, Integer payId, Integer refundId, BigDecimal price) {
        LitemallGiftCardUserLog preLog = litemallGiftCardUserLogService.findById(payId);
        String cardNumber = preLog.getCardNumber();


        //记录退款情况
        LitemallGiftCardUserLog log = new LitemallGiftCardUserLog();
        log.setOrderId(refundId);
        log.setAmount(price);
        log.setType(Constants.LOG_GIFTCARD_REFUND);
        log.setCardNumber(cardNumber);
        log.setContent("退款");
        log.setOrderSource(Constants.ORDER_SOURCE_POS);
        log.setCardUserId(preLog.getCardUserId());
        log.setChangePoints(BigDecimal.ZERO);
        if (cardNumber != null) {
            LitemallGiftCardUser card = litemallGiftCardUserService.findByNumber(cardNumber);
            if (card != null) {
                log.setBalance(card.getAmount().add(price));
                log.setAddUserId(card.getUserId());
            } else {

            }
        }
        litemallGiftCardUserLogService.add(log);

        //更新卡余额
        LitemallGiftCardUser giftCard = litemallGiftCardUserService.findByNumber(cardNumber);
        giftCard.setAmount(giftCard.getAmount().add(price));
        litemallGiftCardUserService.updateById(giftCard);

    }

    /**
     * 生成退款sn
     *
     * @return {@link String}
     */
    private String generateRefundSn() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String now = df.format(LocalDateTime.now());
        return "T" + now + RandomStringUtils.randomAlphanumeric(4);
    }

    /**
     * 退款细节
     * 订单详情
     *
     * @param orderSn 订单sn
     * @param userId  用户id
     * @return 订单详情
     */
    public Response<OrderRefundDetailResponseVO> refundDetail(String orderSn, Integer userId) {
        // 退款信息
//        LitemallRefund litemallRefund = litemallRefundService.findById(refundId);
        LitemallRefund litemallRefund = litemallRefundService.queryByOrderSn(orderSn, userId);
        if (null == litemallRefund) {
            return ResponseUtil.fail(ORDER_REFUND_NOT_EXIST, "退款订单不存在");
        }
        OrderRefundDetailResponseVO response = new OrderRefundDetailResponseVO();
        BeanUtils.copyProperties(litemallRefund, response);

        //设置税费
        List<OrderRefundDetailTaxVO> taxs = new ArrayList<>();
        List<TaxStatisticsDetailVo> taxLs = litemallRefundTaxService.queryByRefundId(litemallRefund.getId());
        if (!CollectionUtils.isEmpty(taxLs)) {
            for (TaxStatisticsDetailVo taxStatisticsDetailVo : taxLs) {
                OrderRefundDetailTaxVO taxVo = new OrderRefundDetailTaxVO();
                taxVo.setCode(taxStatisticsDetailVo.getCode());
                taxVo.setPrice(taxStatisticsDetailVo.getTotalAmount());
                taxs.add(taxVo);
            }
        }
        response.setTaxs(taxs);

        //查询退款商品
        List<OrderRefundDetailGoodsVO> goodsList = new ArrayList<>();
        List<LitemallRefundGoods> refundGoodsLs = litemallRefundGoodsService.findByRefundId(litemallRefund.getId());
        if (!CollectionUtils.isEmpty(refundGoodsLs)) {
            for (LitemallRefundGoods refundGoods : refundGoodsLs) {
                OrderRefundDetailGoodsVO goodsVo = new OrderRefundDetailGoodsVO();
                BeanUtils.copyProperties(refundGoods, goodsVo);

                Integer goodsId = refundGoods.getGoodsId();
                LitemallGoods goods = goodsService.findById(goodsId);
                goodsVo.setGoodsName(goods.getName());
                goodsVo.setSubhead(goods.getSubhead());
                goodsVo.setGoodsSn(goods.getGoodsSn());
                goodsList.add(goodsVo);
            }
        }
        response.setGoodsList(goodsList);

        //用户可用余额
        if (null != userId) {
            LitemallUser user = litemallUserService.findById(userId);
            response.setUserAvailableAmount(user.getAvailableAmount());
        }
        return ResponseUtil.ok(response);
    }




    /**
     * countorder
     *
     * @param shopId 商店id
     * @return {@link Response}<{@link Integer}>
     */
    public Response<Integer> countorder(Integer shopId) {
        List<Short> status = new ArrayList<>(Arrays.asList(new Short[]{OrderUtil.STATUS_CREATE, OrderUtil.STATUS_PAY, OrderUtil.STATUS_SHIP, OrderUtil.STATUS_CONFIRM}));
        return ResponseUtil.ok(orderService.countByShop(shopId, status, true));
    }

    /**
     * 数状态
     *
     * @param userId 用户id
     * @param shopId 商店id
     * @return {@link Response}<{@link Map}<{@link Object}, {@link Object}>>
     */
    public Response<Map<Object, Object>> countByStatus(Integer userId, Integer shopId) {
        Map<Object, Object> map = new HashMap<>();
        List<Short> createStatus = new ArrayList<>(Arrays.asList(new Short[]{OrderUtil.STATUS_CREATE}));
        List<Short> payStatus = new ArrayList<>(Arrays.asList(new Short[]{OrderUtil.STATUS_PAY}));
        List<Short> shipStatus = new ArrayList<>(Arrays.asList(new Short[]{OrderUtil.STATUS_SHIP}));
        List<Short> confirmStatus = new ArrayList<>(Arrays.asList(new Short[]{OrderUtil.STATUS_CONFIRM}));
        map.put("1", orderService.count(userId, createStatus, true));
        map.put("2", orderService.countByShop(shopId, payStatus, true));
        map.put("3", orderService.countByShop(shopId, shipStatus, true));
        map.put("4", orderService.countByShop(shopId, confirmStatus, true));
        return ResponseUtil.ok(map);
    }

    /**
     * 支付
     *
     * @param userId 用户id
     * @param body   身体
     * @return {@link Response}<{@link Object}>
     */
    @Transactional
    public Response<Object> pay(Integer userId, String body) {
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        String cash = JacksonUtil.parseString(body, "cash");
        String change = JacksonUtil.parseString(body, "change");
        Integer memberId = JacksonUtil.parseInteger(body, "memberId");
        if (orderId == null || cash == null || change == null) {
            return ResponseUtil.badArgument();
        }
        LitemallOrder order = orderService.findByUserAndId(userId, orderId);
        if (order == null) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        BigDecimal changeDe = new BigDecimal(change);
        BigDecimal cashDe = new BigDecimal(cash);

        //判断支付现金和订单金额是否匹配
        if (cashDe.subtract(changeDe).subtract(order.getActualPrice()).compareTo(BigDecimal.ZERO) != 0) {
            return ResponseUtil.fail(INVALID_PAY_AMOUNT, "支付金额不正确");
        }

        //检测订单是否是门店订单
        if (!order.getShopOrder()) {
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "订单不能支付");
        }

        //判断门店状态
        Response<Object> error = validShop(order.getShopId());
        if (error != null) {
            return error;
        }


        // 检测是否能够支付
        OrderHandleOption handleOption = OrderUtil.build(order);
        if (!handleOption.isPay()) {
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "订单不能支付");
        }
        LitemallOrder updater = new LitemallOrder();
        updater.setId(order.getId());
        updater.setOrderStatus(OrderUtil.STATUS_PAY);
        updater.setUpdateTime(order.getUpdateTime());
        updater.setPayType(Constants.PAY_TYPE_CASH);
        updater.setPayTime(LocalDateTime.now());
        updater.setMadeStatus(ORDER_MADE_STATUS_NEW);
        updater.setOrderStatus(ORDER_STATUS_ONGOING);
        updater.setUserId(userId);

        if(memberId != null){
            updater.setMemberId(memberId);
        }

        if (orderService.updateWithOptimisticLocker(updater) == 0) {
            return ResponseUtil.updatedDateExpired();
        }
        ;
        //添加订单所收现金表单项
        LitemallOrderCash orderCash = new LitemallOrderCash();
        orderCash.setCash(new BigDecimal(cash));
        orderCash.setOrderPrice(order.getActualPrice());
        orderCash.setChange(new BigDecimal(change));
        orderCash.setOrderId(orderId);
        orderCash.setAddUserId(userId);
        orderCash.setAddUserName(litemallUserService.findById(userId).getUsername());
        if (memberId != null) {
            orderCash.setMemberId(memberId);
        }
        litemallOrderCashService.add(orderCash);

        LitemallOrderVO vo = new LitemallOrderVO();
        BeanUtils.copyProperties(order, vo);

        //发送已支付订单到pos系统，门店开始制作商品
        noticeHelper.noticeShop(MESSAGE_TYPE_PAY, JSON.toJSONString(order.getId()), order.getShopId());
//		pushService.pushMsgToShop("1",order.getShopId());
        return ResponseUtil.ok();
    }

    /**
     * 完整
     *
     * @param userId 用户id
     * @param body   身体
     * @return {@link Response}<{@link Object}>
     */
    public Response<Object> complete(Integer userId, String body) {
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");
        if (orderId == null) {
            return ResponseUtil.badArgument();
        }
        LitemallOrder order = orderService.findById(orderId);
        if (order == null) {
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        // 检测是否已支付
        if (!order.getOrderStatus().equals(OrderUtil.STATUS_PAY)) {
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "订单不能完成");
        }
        LitemallOrder updater = new LitemallOrder();
        updater.setId(order.getId());
        updater.setOrderStatus(OrderUtil.STATUS_SHIP);
        updater.setUpdateTime(order.getUpdateTime());
        orderService.updateWithOptimisticLocker(updater);


        /**
         * TODO 这里可能需要对接视频或音频，提醒客户取餐
         */


        return ResponseUtil.ok();
    }

    /**
     * 订单直接
     * 跳过添加购物车、直接下单
     *
     * @param shopId  商店id
     * @param userId  用户id
     * @param cartDto 购物车dto
     * @return {@link Response}<{@link Object}>
     */
    @Transactional
    public Response<Object> orderDirectly(Integer shopId, Integer userId, AdminCartDTO cartDto) {
        Response<Object> error = validShop(shopId);
        if (error != null) {
            return error;
        }
        Integer productId = cartDto.getProductId();
        Integer number = cartDto.getNumber().intValue();
        Integer goodsId = cartDto.getGoodsId();
        Integer[] specIds = cartDto.getSpecificationIds();
        if (!ObjectUtils.allNotNull(productId, number, goodsId, shopId)) {
            return ResponseUtil.badArgument();
        }
        if (number <= 0) {
            return ResponseUtil.badArgument();
        }

        //判断商品是否可以购买
        LitemallGoods goods = goodsService.findById(goodsId);
        if (goods == null || !goods.getIsOnSale()) {
            return ResponseUtil.fail(GOODS_UNSHELVE, "商品已下架");
        }
        LitemallGoodsProduct product = productService.findById(productId);
        List<LitemallGoodsSpecification> specifications = goodsSpecificationService.queryByIds(specIds);
        /**
         * 商品价格
         */
        BigDecimal checkedGoodsPrice = new BigDecimal(0.00);
        checkedGoodsPrice = checkedGoodsPrice.add(product.getSellPrice());
        for (LitemallGoodsSpecification sp : specifications) {
            checkedGoodsPrice = checkedGoodsPrice.add(sp.getPrice());
        }

        /**
         * 获取门店对应的税费率
         */
        List<LitemallShopRegion> shopRegions = litemallShopRegionService.queryByShopId(shopId);
        List<LitemallTax> litemallTaxes = litemallTaxService.queryByRegionIds(shopRegions.stream().map(LitemallShopRegion::getRegionId).collect(Collectors.toList()));

        List<LitemallOrderTax> orderTaxes = new ArrayList<>();
        BigDecimal tax = new BigDecimal(0.00);
        List<Integer> taxTypes = new ArrayList<>(Arrays.asList(product.getTaxTypes()));
        for (LitemallTax item : litemallTaxes) {
            boolean anyMatch = taxTypes.stream().anyMatch(type -> {
                return type == item.getType().intValue();
            });
            if (anyMatch) {
                //计算税率
                tax = tax.add(item.getValue().divide(new BigDecimal(100.00)));
                /**
                 * 记录订单税费项
                 */
                LitemallOrderTax orderTax = new LitemallOrderTax();
                orderTax.setCode(item.getCode());
                orderTax.setName(item.getName());
                orderTax.setType(item.getType());
                orderTax.setValue(item.getValue());
                orderTaxes.add(orderTax);
            }
        }
        BigDecimal taxGoodsPrice = new BigDecimal(0.00);
        //税费 = 商品价格 * 商品数量 * 税率
        taxGoodsPrice = taxGoodsPrice.add(tax.multiply(checkedGoodsPrice.multiply(new BigDecimal(number))));

        BigDecimal actualPrice = checkedGoodsPrice.add(taxGoodsPrice);

        LitemallOrder order = new LitemallOrder();
        order.setUserId(userId);
        order.setOrderSn(orderService.generateOrderSn(userId));
        order.setOrderStatus(OrderUtil.STATUS_CREATE);
        order.setConsignee("");
        order.setMobile("");
        order.setMessage("");
        order.setAddress("");
        order.setGoodsPrice(checkedGoodsPrice);
        order.setFreightPrice(new BigDecimal(0.00));
        order.setCouponPrice(new BigDecimal(0.00));
        order.setIntegralPrice(new BigDecimal(0.00));
        order.setOrderPrice(new BigDecimal(0.00));
        order.setActualPrice(actualPrice);
        order.setTaxPrice(taxGoodsPrice);
        order.setShopId(shopId);
        order.setOrderType(cartDto.getOrderType());
        order.setShopOrder(true);

        Integer orderId = null;
        // 添加订单表项
        orderService.add(order);
        orderId = order.getId();

        // 订单商品
        LitemallOrderGoods orderGoods = new LitemallOrderGoods();
        orderGoods.setOrderId(order.getId());
        orderGoods.setGoodsId(goods.getId());
        orderGoods.setGoodsSn(goods.getGoodsSn());
        orderGoods.setProductId(productId);
        orderGoods.setGoodsName(goods.getName());
        orderGoods.setPicUrl(goods.getPicUrl());
        orderGoods.setPrice(product.getSellPrice());
        orderGoods.setNumber(number.shortValue());
        List<String> specificationStrs = specifications.stream().map(s -> {
            return s.getSpecification();
        }).collect(Collectors.toList());
        orderGoods.setSpecifications(specificationStrs.toArray(new String[]{}));
        orderGoods.setAddTime(LocalDateTime.now());
//        orderGoods.setTaxPrice(product.getTax());

        orderGoodsService.add(orderGoods);


        // 商品货品数量减少
        Integer remainNumber = product.getNumber() - number;
        if (remainNumber < 0) {
            throw new RuntimeException("下单的商品货品数量大于库存量");
        }
        if (productService.reduceStock(productId, number.shortValue()) == 0) {
            throw new RuntimeException("商品货品库存减少失败");
        }
        Map<String, Object> data = new HashMap<>();
        data.put("orderId", orderId);

        return ResponseUtil.ok();
    }

    /**
     * 有效商店
     *
     * @param shopId 商店id
     * @return {@link Response}<{@link Object}>
     */
    private Response<Object> validShop(Integer shopId) {
        if (shopId == null) {
            return ResponseUtil.fail(SHOP_NOT_EXSIT, "门店不存在");
        }
        LitemallShop litemallShop = shopService.findById(shopId);
        //判断门店状态
        if (litemallShop == null || !litemallShop.getStatus().equals(Constants.SHOP_STATUS_OPEN)) {
            return ResponseUtil.fail(SHOP_UNABLE, "门店未开业");
        } else {
            String closeTime = litemallShop.getCloseTime();
            String openTime = litemallShop.getOpenTime();
            DateTimeFormatter timeDtf = DateTimeFormatter.ofPattern("HH:mm");
            LocalTime startTimes = LocalTime.parse(openTime, timeDtf);
            LocalTime endTime = LocalTime.parse(closeTime, timeDtf);
            LocalTime now = LocalTime.now();
            Integer dayOfWeek = LocalDateTime.now().getDayOfWeek().getValue();
            //判断星期
            if (litemallShop.getWeeks() != null && !Arrays.asList(litemallShop.getWeeks()).contains(dayOfWeek)) {
                return ResponseUtil.fail(SHOP_CLOSED, "门店已歇业");
            }
            //判断每天开业时间
            if (!(now.compareTo(startTimes) == 1 && now.compareTo(endTime) == -1)) {
                return ResponseUtil.fail(SHOP_CLOSED, "门店已歇业");
            }
        }
        /* if(!Arrays.asList(litemallShop.getTypes()).contains(orderType)){
            return ResponseUtil.fail(SHOP_UNSUPPOT, "不支持该服务");
        }*/
        return null;
    }

    /**
     * 计算订单
     *
     * @param userId              用户id
     * @param calculationOrderVos 计算订单vos
     * @return {@link Response}<{@link Map}<{@link String}, {@link Object}>>
     */
    public Response<Map<String, Object>> calculationOrder(Integer userId, List<CalculationOrderVO> calculationOrderVos) {
        if (calculationOrderVos == null || calculationOrderVos.size() == 0) {
            return ResponseUtil.badArgument();
        }
        List<Short> status = new ArrayList<>(Arrays.asList(new Short[]{OrderUtil.STATUS_CONFIRM, OrderUtil.STATUS_AUTO_CONFIRM}));

        //获取订单总价
        List<LitemallOrder> litemallOrders = orderService.queryByOrderStatus(userId, status, true);
        BigDecimal totalAmount = new BigDecimal(0.0);
        for (LitemallOrder order : litemallOrders) {
            totalAmount = totalAmount.add(order.getActualPrice());
        }
        //比较输入价格和订单总价
        BigDecimal inputAmount = new BigDecimal(0.0);
        for (CalculationOrderVO vo : calculationOrderVos) {
            inputAmount = inputAmount.add(vo.getAmount().multiply(vo.getNumber()));
        }

        Map<String, Object> map = new HashMap<>();
        map.put("totalAmount", totalAmount);
        map.put("inputAmount", inputAmount);
        return ResponseUtil.ok(map);
    }

    /**
     * takedone
     *
     * @param userId 用户id
     * @param body   身体
     * @return {@link Response}<{@link Object}>
     */
    public synchronized Response<Object> takedone(Integer userId, String body) {
        Integer orderId = JacksonUtil.parseInteger(body, "orderId");

        LitemallOrder updater = new LitemallOrder();
        updater.setId(orderId);
        updater.setOrderStatus(OrderUtil.STATUS_CONFIRM);
        updater.setUpdateTime(LocalDateTime.now());
        orderService.updateById(updater);


        /*LitemallOrder order = orderService.findById(orderId);
//        OrderHandleOption handleOption = OrderUtil.build(order);
        if (!order.getOrderStatus().equals((short) 201) || !order.getMadeStatus().equals((byte) 2)) {
            return ResponseUtil.fail(ORDER_INVALID_OPERATION, "订单不能完成");
        }

        LitemallOrder updater = new LitemallOrder();
        updater.setId(order.getId());
        updater.setOrderStatus(OrderUtil.STATUS_CONFIRM);
        updater.setUpdateTime(order.getUpdateTime());
        orderService.updateWithOptimisticLocker(updater);*/
//        noticeHelper.noticeShop(MESSAGE_TYPE_POS, JSON.toJSONString(updater), updater.getShopId());

        //订单消耗量
        /*List<LitemallOrderGoods> litemallOrderGoods = orderGoodsService.queryByOid(orderId);
        litemallOrderGoods.stream().forEach(orderGoods->{
            List<LitemallGoodsAccessory> goodsAccessoryList = litemallGoodsAccessoryService.goodsAllMerchandise(orderGoods.getGoodsId());
            for (LitemallGoodsAccessory goodsAccessory:goodsAccessoryList){
                LitemallMerchandise merchandise = litemallMerchandiseService.findById(goodsAccessory.getMerchandiseId());
                //设置商品消耗量
                LitemallOrderMerchandise orderMerchandise = new LitemallOrderMerchandise();
                orderMerchandise.setId((int) DateUtil.currentSeconds());
                orderMerchandise.setOrderId(orderGoods.getOrderId());
                orderMerchandise.setShopId(orderGoods.getShopId());
                orderMerchandise.setOrderGoodsId(orderGoods.getId());
                orderMerchandise.setGoodsId(orderGoods.getGoodsId());
                orderMerchandise.setGoodsName(orderGoods.getGoodsName());
                orderMerchandise.setGoodsSn(orderGoods.getGoodsSn());
                orderMerchandise.setMerchandiseId(goodsAccessory.getMerchandiseId());
                orderMerchandise.setMerchandiseSn(merchandise.getMerchandiseSn());
                orderMerchandise.setMerchandiseName(merchandise.getName());
                //消耗系数
                orderMerchandise.setConsumerNumber(goodsAccessory.getConsumeRatio().multiply(new BigDecimal(goodsAccessory.getNumber())).multiply(new BigDecimal(orderGoods.getNumber())).multiply(goodsAccessory.getDosage()));
                orderMerchandise.setDeleted(false);
                orderMerchandiseService.add(orderMerchandise);
            }
        });*/
        return ResponseUtil.ok();
    }

    /**
     * 得到手订单列表
     * 获取门店中所有挂单订单列表
     *
     * @param orderId 订单id
     * @param shopId  商店id
     * @param userId  用户id
     * @return {@link List}<{@link HandOrderVO}>
     */
    public List<HandOrderVO> getHandOrderList(Integer orderId, Integer shopId, Integer userId) {
        List<LitemallOrder> orders = orderService.queryHangOrderList(shopId, userId);
        List<HandOrderVO> handOrderVos = new ArrayList<>();
        orders.stream().forEach(order -> {
            HandOrderVO vo = getHandOrder(order.getId());

            //如果是挂单的订单，则添加标志已选中
            if (orderId != null && orderId.equals(order.getId())) {
                vo.setIsSelected(true);
            }

            if (vo != null) {
                handOrderVos.add(vo);
            }
        });
        return handOrderVos;
    }

    /**
     * 得到手订单
     * 获取单个挂单订单信息
     *
     * @param orderId 订单id
     * @return {@link HandOrderVO}
     */
    public HandOrderVO getHandOrder(Integer orderId) {
        List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);

        if (orderGoodsList.size() > 0) {
            List<String> goodsNames = orderGoodsList.stream().map(LitemallOrderGoods::getGoodsName).collect(Collectors.toList());

            //挂单信息
            HandOrderVO vo = new HandOrderVO();
            vo.setOrderId(orderId);
            vo.setGoodsNames(goodsNames);

            return vo;
        } else {
            return null;
        }
    }

    /**
     * 更新状态交货
     *
     * @param orderId   订单id
     * @param orderType 订单类型
     * @return {@link Response}<{@link OrderDetailResponseVO}>
     */
    public Response<OrderDetailResponseVO> updateStatusDelivery(Integer orderId, Byte orderType) {
        LitemallOrder order = new LitemallOrder();
        order.setId(orderId);
        order.setOrderType(orderType);
        orderService.updateById(order);
        return detail(orderId);
    }

    /**
     * 按日期查询或sn
     *
     * @param useDate     使用日期
     * @param orderSn     订单sn
     * @param page        页面
     * @param limit       限制
     * @param sort        排序
     * @param ord         奥德
     * @param shopId      商店id
     * @param orderStatus
     * @return {@link Object}
     */
    @SneakyThrows
    public Object queryByDateOrSn(String useDate, String orderSn, Integer page, Integer limit, String sort, String ord, Integer shopId, Integer orderStatus) {

        IPage<LitemallOrder> orderIPage = orderService.page(new Page<>(page,limit),Wrappers.lambdaQuery(LitemallOrder.class)
                .eq(shopId!=0,LitemallOrder::getShopId, shopId)
                .like(StrUtil.isNotEmpty(orderSn),LitemallOrder::getOrderSn,orderSn)
                .isNotNull(LitemallOrder::getPayType)
                .eq(orderStatus!=null,LitemallOrder::getOrderStatus,orderStatus)
                .between(StrUtil.isNotBlank(useDate),LitemallOrder::getAddTime,useDate+" 00:00:00", useDate+" 23:59:59")
                .eq(LitemallOrder::getDeleted, 0)
                .orderByDesc(LitemallOrder::getAddTime));

        QueryWrapper<LitemallOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("sum(actual_price) as amountTotal");
        queryWrapper.eq(shopId != 0, "shop_id", shopId);

        // 查询当天的订单
        queryWrapper.between(StrUtil.isNotEmpty(useDate),"add_time",useDate+" 00:00:00", useDate+" 23:59:59");

        queryWrapper.isNotNull("pay_type");
        queryWrapper.like(StrUtil.isNotBlank(orderSn), "order_sn", orderSn);
        queryWrapper.eq("deleted", 0);
        queryWrapper.orderByDesc("add_time");

        Map<String, Object> map = orderService.getMap(queryWrapper);
        Map resultMap= CollUtil.newHashMap();
        resultMap.put("list",orderIPage);
        resultMap.put("amountTotal",map.get("amountTotal"));
        return ResponseUtil.success(resultMap);
    }

    /**
     * sn查询退款订单
     *
     * @param orderSn 订单sn
     * @param page    页面
     * @param limit   限制
     * @param sort    排序
     * @param ord     奥德
     * @param userId  用户id
     * @return {@link Object}
     */
    public Object queryRefundByOrderSn(String orderSn,Integer shopId, Integer page, Integer limit, String sort, String ord, Integer userId) {
        List<Short> orderStatus = new ArrayList<>(Arrays.asList(new Short[]{ORDER_STATUS_ONGOING}));

        //List<LitemallOrder> orders = orderService.queryRefundByOrderSn(orderSn, null, page, limit, "add_time", ord, userId);
        List<LitemallOrder> orders = orderService.page(new Page(page,limit),Wrappers.lambdaQuery(LitemallOrder.class)
                .like(LitemallOrder::getOrderSn,orderSn)
                .eq(LitemallOrder::getDeleted,false)
                .and(wrapper->wrapper
                        .eq(LitemallOrder::getMadeStatus,ORDER_MADE_STATUS_NEW)
                        .or()
                        .eq(LitemallOrder::getOrderStatus,STATUS_REFUND_CONFIRM))
        ).getRecords();

        List<OrderListResponseVO> vos = orders.stream().map(o -> {
            LitemallShop litemallShop = shopService.findById(o.getShopId());
            OrderListResponseVO orderListVo = new OrderListResponseVO();
            //BeanUtils.copyProperties(o,orderListVo);
            orderListVo.setId(o.getId());
            orderListVo.setShopName(ObjectUtil.isNotNull(litemallShop)?litemallShop.getName():litemallShop.getName());
            orderListVo.setShopId(o.getShopId());
            orderListVo.setOrderSn(o.getOrderSn());
            orderListVo.setSerialNo(o.getSerialNo());
            orderListVo.setOrderPrice(o.getOrderPrice());
            orderListVo.setActualPrice(o.getActualPrice());
            orderListVo.setGoodsPrice(o.getGoodsPrice());
            orderListVo.setTaxPrice(o.getTaxPrice());
            orderListVo.setOrderStatus(o.getOrderStatus());
            orderListVo.setOrderSource(o.getOrderSource());
            orderListVo.setOrderType(o.getOrderType());
            orderListVo.setPayType(o.getPayType());
            orderListVo.setMadeStatus(o.getMadeStatus());
            orderListVo.setOriginalSn(o.getOriginalSn());
            orderListVo.setIsRepeat(o.getIsRepeat());

            List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(o.getId());
            List<OrderListGoodsVO> goods = new ArrayList<>();
            String goodsNames = "";
            for (LitemallOrderGoods orderGoods : orderGoodsList) {
                OrderListGoodsVO orderListGoodsVo = new OrderListGoodsVO();
                //BeanUtils.copyProperties(orderGoods,orderListGoodsVo);
                orderListGoodsVo.setId(orderGoods.getId());
                orderListGoodsVo.setGoodsName(orderGoods.getGoodsName());
                orderListGoodsVo.setNumber(orderGoods.getNumber());
                orderListGoodsVo.setPicUrl(orderGoods.getPicUrl());
                orderListGoodsVo.setSellingPrice(orderGoods.getSellingPrice());
                orderListGoodsVo.setTaxPrice(orderGoods.getTaxPrice());
                orderListGoodsVo.setGoodsPrice(orderGoods.getSellingPrice().multiply(new BigDecimal(orderGoods.getNumber())));
                orderListGoodsVo.setPrice(orderGoods.getPrice());
                orderListGoodsVo.setRefundNumber(orderGoods.getRefundNumber());
                orderListGoodsVo.setAvaliableRefundNumber(orderGoods.getNumber() - orderGoods.getRefundNumber());
                orderListGoodsVo.setRemark(JSONUtil.toJsonStr(orderGoods.getRemark()));
                orderListGoodsVo.setRefundTime(orderGoods.getRefundTime());
                //查询规格辅料
                String[] specifications = orderGoods.getSpecifications();
                StringBuffer specAndAccessory = new StringBuffer(specifications[0]);
                //商品属性
                String property = getGoodsPropertyStr(orderGoods.getId());
                if (StringUtils.isNotBlank(property)) {
                    specAndAccessory.append("\r\n").append(property);
                }
                String accessory = getGoodsAccessoryStr(orderGoods.getId());
                if (StringUtils.isNotBlank(accessory)) {
                    specAndAccessory.append("\r\n").append(accessory);
                }
                orderListGoodsVo.setSpecAndAccessory(specAndAccessory.toString());
                goodsNames += orderGoods.getGoodsName();

                //查询商品是否是可退款商品
                //LitemallGoods gs = goodsService.findById(orderGoods.getGoodsId());
                orderListGoodsVo.setIsReturnGoods(true);
                goods.add(orderListGoodsVo);
            }

            orderListVo.setGoods(goods);
            orderListVo.setGoodsNames(goodsNames);
            orderListVo.setOrderDate(o.getAddTime().toLocalDate().toString());
            return orderListVo;
        }).collect(Collectors.toList());

        return vos.size() == 0?ResponseUtil.fail(ORDER_UNKNOWN, "订单已完成"): ResponseUtil.ok(vos.get(0));
    }

    /**
     * 在烹饪食谱
     * 订单配方
     *
     * @param orderId 订单id
     * @return {@link OrderRecipeResponseVO}
     */
    public OrderRecipeResponseVO recipeInCook(Integer orderId) {
        LitemallOrder litemallOrder = orderService.findById(orderId);
        if (null == litemallOrder) {
            return null;
        }
        OrderRecipeResponseVO response = new OrderRecipeResponseVO();
        BeanUtils.copyProperties(litemallOrder, response);

        List<OrderRecipeGoodsVO> result = new ArrayList<>();

        List<String> remarks = new ArrayList<>();

        //查询订单商品
        List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);

        if (!CollectionUtils.isEmpty(orderGoodsList)) {
            for (LitemallOrderGoods orderGoods : orderGoodsList) {
                OrderRecipeGoodsVO recipe = new OrderRecipeGoodsVO();
                BeanUtils.copyProperties(orderGoods, recipe);

                recipe.setSpecifications(orderGoods.getSpecifications()[0]);
                recipe.setAccessory(getGoodsAccessoryList(orderGoods.getId()));
                recipe.setPropertys(getGoodsPropertyList(orderGoods.getId()));

                // 获取商品备注信息并转换为 JSON 字符串
                remarks.add( ObjectUtil.isNotNull(orderGoods) ? JSONUtil.toJsonStr(orderGoods.getRemark()) : null);

                List<OrderRecipeMerVO> merList = new ArrayList<>();
                Map<Integer, BigDecimal> merMap = caculateMerchandise(orderGoods, false);
                for (Integer merchandiseId : merMap.keySet()) {
                    OrderRecipeMerVO recipeMerVo = new OrderRecipeMerVO();
                    //查询原料信息
                    LitemallMerchandise litemallMerchandise = litemallMerchandiseService.findById(merchandiseId);
                    recipeMerVo.setMerchandiseId(merchandiseId);
                    recipeMerVo.setMerchandiseName(litemallMerchandise.getName());
                    recipeMerVo.setMerchandiseSn(litemallMerchandise.getMerchandiseSn());
                    recipeMerVo.setNumber(merMap.get(merchandiseId));
                    recipeMerVo.setUnit(litemallMerchandise.getBasicUnit());
                    merList.add(recipeMerVo);
                }
                recipe.setMerList(merList);
                result.add(recipe);
            }
        }

        response.setMessage(CollUtil.isEmpty(remarks) ? null : remarks.get(0));
        response.setGoodsList(result);
        return response;
    }

//    /**
//     * 菜谱做
//     *
//     * @param shopId 商店id
//     * @return {@link Object}
//     */
//    public Object recipeDoing(Integer shopId) {
//        List<Byte> madeStatus = new ArrayList<>(Arrays.asList(new Byte[]{0, 1}));
//        List<LitemallOrder> litemallOrders = orderService.recipeDoingByMadeStatusInShop(madeStatus, shopId);
//        List<OrderRecipeResponseVO> recipeResponses = new ArrayList<>();
//        for (LitemallOrder order : litemallOrders) {
//            OrderRecipeResponseVO recipeResponse = recipeInCook(order.getId());
//            //用户昵称
//            LitemallUser litemallUser = litemallUserService.getOne(Wrappers.lambdaQuery(LitemallUser.class)
//                    .eq(LitemallUser::getId,order.getUserId())
//            );
//            recipeResponse.setNickname(litemallUser.getNickname());
//            recipeResponse.setMessage(order.getMessage());
//            List<LitemallOrderGoods> litemallOrderGoods = orderGoodsService.queryByOid(order.getId());
//            litemallOrderGoods.stream().forEach(litemallOrderGoods1 -> {
//                recipeResponse.setMessage(ObjectUtil.isNotNull(litemallOrderGoods1)?JSONUtil.toJsonStr(litemallOrderGoods1.getRemark()):null);
//            });
//            recipeResponses.add(recipeResponse);
//        }
//
//        return ResponseUtil.okList(recipeResponses);
//    }

    /**
     * 查询制作中和已完成的订单，并返回制作订单详情。
     *
     * @param shopId 店铺ID
     * @return 包含制作订单详情的响应对象
     */
    public Object recipeDoing(Integer shopId) {
        // 查询制作中和已完成的订单状态列表
        List<Byte> madeStatus = new ArrayList<>(Arrays.asList(new Byte[]{0, 1}));
        logger.info("查询制作中和已完成的订单状态列表");
        // 查询指定店铺中制作中和已完成的订单列表
        List<LitemallOrder> litemallOrders = orderService.recipeDoingByMadeStatusInShop(madeStatus, shopId);
        logger.info("查询指定店铺中制作中和已完成的订单列表");
        // 初始化制作订单详情列表
        List<OrderRecipeResponseVO> recipeResponses = new ArrayList<>();
        logger.info("初始化制作订单详情列表");
        // 遍历订单列表，生成制作订单详情
        for (LitemallOrder order : litemallOrders) {
            // 获取订单ID
            Integer orderId = order.getId();
            logger.info("获取订单ID" + orderId);
            // 查询订单关联的用户信息
            LitemallUser user = litemallUserService.getOne(Wrappers.lambdaQuery(LitemallUser.class)
                    .eq(LitemallUser::getId, order.getUserId()));
            logger.info("查询订单关联的用户信息");
            String nickname = (user != null) ? user.getNickname() : null;
            logger.info("获取订单名称" + nickname);
            // 构建制作订单详情对象
            OrderRecipeResponseVO recipeResponse = recipeInCook(orderId);
            recipeResponse.setNickname(nickname);
            recipeResponse.setMessage(order.getMessage());
            logger.info("构建制作订单详情对象");
            // 查询订单关联的商品信息
            List<LitemallOrderGoods> litemallOrderGoods = orderGoodsService.queryByOid(orderId);
            // 处理订单商品备注信息并添加到制作订单详情中
            litemallOrderGoods.stream().forEach(orderGoods -> {
                recipeResponse.setMessage(ObjectUtil.isNotNull(orderGoods) ? JSONUtil.toJsonStr(orderGoods.getRemark()) : null);
            });
            logger.info("处理订单商品备注信息并添加到制作订单详情中");
            // 将制作订单详情添加到列表中
            recipeResponses.add(recipeResponse);
            logger.info("将制作订单详情添加到列表中");
        }

        // 返回制作订单详情列表的响应对象
        return ResponseUtil.okList(recipeResponses);
    }



    /**
     * 菜谱做
     *
     * @param shopId 商店id
     * @return {@link Object}
     */
    public Object recipeDone(Integer shopId) {
//        List<Byte> madeStatus = new ArrayList<>(Arrays.asList(new Byte[]{2,-1}));
//        List<LitemallOrder> litemallOrders = orderService.recipeDoneByMadeStatusInShop(madeStatus, shopId);
//        List<OrderRecipeResponseVO> recipeResponses = new ArrayList<>();
//        litemallOrders.stream().forEach(order -> {
//            OrderRecipeResponseVO recipeResponse = recipeInCook(order.getId());
//            //用户昵称
//            LitemallUser litemallUser = litemallUserService.getOne(Wrappers.lambdaQuery(LitemallUser.class)
//                    .eq(LitemallUser::getId,order.getUserId())
//            );
//            recipeResponse.setNickname(litemallUser.getNickname());
//            List<LitemallOrderGoods> litemallOrderGoods = orderGoodsService.queryByOid(order.getId());
//            litemallOrderGoods.stream().forEach(litemallOrderGoods1 -> {
//                recipeResponse.setMessage(ObjectUtil.isNotNull(litemallOrderGoods1)?JSONUtil.toJsonStr(litemallOrderGoods1.getRemark()):null);
//            });
//            recipeResponse.setOrderStatus(order.getOrderStatus());
//            recipeResponses.add(recipeResponse);
//        });
//
//        return ResponseUtil.okList(recipeResponses);

        // 定义订单制作状态列表
        List<Byte> madeStatus = new ArrayList<>(Arrays.asList(new Byte[]{2, -1}));
        // 查询指定店铺中已完成的订单列表
        List<LitemallOrder> litemallOrders = orderService.recipeDoneByMadeStatusInShop(madeStatus, shopId);
        // 创建存储订单制作响应对象的列表
        List<OrderRecipeResponseVO> recipeResponses = new ArrayList<>();
        // 遍历已完成的订单列表
        litemallOrders.stream().forEach(order -> {
            // 获取订单的制作响应对象
            OrderRecipeResponseVO recipeResponse = recipeInCook(order.getId());
            // 获取用户昵称
            LitemallUser litemallUser = litemallUserService.getOne(Wrappers.lambdaQuery(LitemallUser.class)
                    .eq(LitemallUser::getId, order.getUserId())
            );
            recipeResponse.setNickname(litemallUser.getNickname());
            // 查询订单的商品列表
            List<LitemallOrderGoods> litemallOrderGoods = orderGoodsService.queryByOid(order.getId());
            // 遍历订单的商品列表
            litemallOrderGoods.stream().forEach(litemallOrderGoods1 -> {
                // 设置订单商品的备注信息
                recipeResponse.setMessage(ObjectUtil.isNotNull(litemallOrderGoods1) ? JSONUtil.toJsonStr(litemallOrderGoods1.getRemark()) : null);
            });
            // 设置订单状态
            recipeResponse.setOrderStatus(order.getOrderStatus());
            // 将订单制作响应对象添加到列表中
            recipeResponses.add(recipeResponse);
        });
        // 返回包含订单制作响应对象列表的响应对象
        return ResponseUtil.okList(recipeResponses);
    }

    /**
     * 查询已完成的订单状态列表并返回响应对象。
     *
     * @param shopId 店铺ID
     * @return 包含响应对象的响应实体
     */
    //@Async
    public Object getCompletedOrdersInShop(Integer shopId) {
        Lock lock = new ReentrantLock();
        try {
            lock.lock();
            // 查询已完成的订单状态列表
            List<Byte> completedStatusList = Arrays.asList((byte) 2, (byte) -1);
            logger.info("订单状态列表");
            // 查询指定店铺中已完成的订单列表
            List<LitemallOrder> completedOrders = orderService.recipeDoneByMadeStatusInShop(completedStatusList, shopId);
            logger.info("店铺中已完成的订单列表");
            // 处理已完成的订单列表并生成响应列表
            List<OrderRecipeResponseVO> recipeResponses = completedOrders.stream()
                    .map(order -> {
                        try {
                            // 获取订单ID
                            Integer orderId = order.getId();
                            logger.info("orderId:" + orderId);
                            // 查询订单关联的用户信息
                            LitemallUser user = litemallUserService.getById(order.getUserId());
                            String nickname = (user != null) ? user.getNickname() : null;
                            logger.info("nickname:" + nickname);
                            // 查询订单关联的商品信息
                            /*List<LitemallOrderGoods> orderGoodsList = orderGoodsService.queryByOid(orderId);
                            List<String> remarks = orderGoodsList.stream()
                                    .map(orderGoods -> {
                                        // 获取商品备注信息并转换为 JSON 字符串
                                        return ObjectUtil.isNotNull(orderGoods) ? JSONUtil.toJsonStr(orderGoods.getRemark()) : null;
                                    })
                                    .collect(Collectors.toList());*/
                            logger.info("关联的商品信息");

                            // 构建订单响应对象
                            OrderRecipeResponseVO recipeResponse = recipeInCook(orderId);
                            recipeResponse.setNickname(nickname);
                            //recipeResponse.setMessage(CollUtil.isEmpty(remarks) ? null : remarks.get(0));
                            recipeResponse.setOrderStatus(order.getOrderStatus());
                            return recipeResponse;
                        } catch (Exception e) {
                            // 异常处理，记录日志并返回null
                            logger.error("Failed to process order: " + order.getId(), e);
                            return null;
                        }
                    })
                    .filter(Objects::nonNull) // 过滤掉处理异常后返回的null对象
                    .collect(Collectors.toList());

            // 返回响应对象
            return ResponseUtil.okList(recipeResponses);
        } catch (Exception e) {
            // 异常处理，记录日志并返回异常响应
            logger.error("Failed to fetch completed orders", e);
            return ResponseUtil.fail("Failed to fetch completed orders");
        }finally {
            lock.unlock();
        }
    }


    /**
     * 订单查询「订单号、会员名称、会员信息(手机号｜邮箱)」
     * @param shopId
     * @param searchKey
     * @return
     */
    public Object orderSearch(Integer shopId, String searchKey,Integer madeStatus,Integer page,Integer limit) {
        List<LitemallOrder> litemallOrders = orderService.selectJoinList(LitemallOrder.class,new MPJLambdaWrapper<LitemallOrder>()
                .selectAll(LitemallOrder.class)
                .leftJoin(LitemallUser.class, LitemallUser::getId, LitemallOrder::getUserId)
                .between(LitemallOrder::getPayTime,LocalDateTime.of(LocalDate.now(), LocalTime.MIN), LocalDateTime.of(LocalDate.now(), LocalTime.MAX))
                .between(LitemallOrder::getAddTime,LocalDateTime.of(LocalDate.now(), LocalTime.MIN), LocalDateTime.of(LocalDate.now(), LocalTime.MAX))
                .eq(shopId != null, LitemallOrder::getShopId, shopId)
                .eq(madeStatus != null, LitemallOrder::getMadeStatus, madeStatus)
                .eq( LitemallOrder::getOrderStatus, 401)
                        .and(wrapper-> wrapper
                .like(LitemallOrder::getOrderSn,searchKey)
                .or()
                .eq(LitemallUser::getUsername,searchKey)
                .or()
                .eq(LitemallUser::getMobile,searchKey)
                .or()
                .eq(LitemallUser::getEmail,searchKey))
        );
        List<OrderRecipeResponseVO> recipeResponses = new ArrayList<>();
        litemallOrders.stream().forEach(order -> {
            OrderRecipeResponseVO recipeResponse = recipeInCook(order.getId());
            //用户昵称
            LitemallUser litemallUser = litemallUserService.getOne(Wrappers.lambdaQuery(LitemallUser.class)
                    .eq(LitemallUser::getId,order.getUserId())
            );
            recipeResponse.setNickname(litemallUser.getNickname());
            List<LitemallOrderGoods> litemallOrderGoods = orderGoodsService.queryByOid(order.getId());
            litemallOrderGoods.stream().forEach(litemallOrderGoods1 -> {
                recipeResponse.setMessage(ObjectUtil.isNotNull(litemallOrderGoods1)?JSONUtil.toJsonStr(litemallOrderGoods1.getRemark()):null);
            });
            recipeResponses.add(recipeResponse);
        });
        return ResponseUtil.okList(recipeResponses);
    }

    /**
     * 查询没有支付,没有选择
     *
     * @param shopId 商店id
     * @param userId 用户id
     * @return {@link Response}<{@link SocketQueryVO}>
     */
    public Response<SocketQueryVO> queryNoPaidAndNoPick(Integer shopId, Integer userId) {
        //已付款数量
        Integer paidNum = orderService.queryPaid(shopId, userId);

        //待付款数量
        Integer noPaidNum = orderService.queryNotPaid(shopId, userId);

        //待取餐数量
        Integer noPickNum = orderService.queryNotPickUp(shopId, userId);

        //已完成订单数量
        Integer doneNum = orderService.queryDone(shopId, userId);

        //挂单数量
        Integer hangNum = orderService.queryHangOrder(shopId, userId);

        SocketQueryVO vo = new SocketQueryVO();
        vo.setOutGoingOrderNum(paidNum);
        vo.setHangOrderNum(hangNum);
        vo.setDoneNum(doneNum);
        vo.setNoPickNum(noPickNum);
        vo.setNoPaidNum(noPaidNum);

        return ResponseUtil.ok(vo);
    }

    /**
     * 得到订单货物vos
     *
     * @param orderId 订单id
     * @return {@link Object}
     */
    public Object getOrderGoodsVos( Integer orderId,Integer userId) {
        LitemallOrder order = orderService.findById(orderId);
        if(order == null){
            return ResponseUtil.fail(ORDER_UNKNOWN, "订单不存在");
        }
        Integer shopId = order.getShopId();
        LitemallOrderVO vo = new LitemallOrderVO();
        List<LitemallOrderGoods> litemallOrderGoods = litemallOrderGoodsMapper.selectList(Wrappers.lambdaQuery(LitemallOrderGoods.class).eq(LitemallOrderGoods::getOrderId, orderId));
        litemallOrderGoods.stream().forEach(orderGoods -> {
            vo.setMessage(StringUtils.isNotBlank(JSONUtil.toJsonStr(orderGoods.getRemark()))?JSONUtil.toJsonStr(orderGoods.getRemark()):null);
        });
        BeanUtils.copyProperties(order, vo);
        vo.setUserId(userId);
        vo.setTotal(order.getActualPrice());
        vo.setSerialNo( orderService.getTodayMaxSerialNo(shopId)+1);
        vo.setSerinalNumber( order.getSerinalNumber());
        List<LitemallOrderGoods> orderGoods = orderGoodsService.queryByOid(vo.getId());

        BigDecimal subTotal = new BigDecimal(0.0);
        List<LitemallOrderGoodsVO> vos = orderGoods.stream().map(og -> {

            StringBuffer ss = new StringBuffer();
            if (og.getSpecifications().length != 0) {
                for (int i = 0; i < og.getSpecifications().length; i++) {
                    ss.append(og.getSpecifications()[i]);
                    if (i < og.getSpecifications().length - 1) {
                        ss.append("\r\n");
                    }
                }
            }

//        	//属性
            List<LitemallOrderFormulaMaterial> orderFormulaMaterials = litemallOrderFormulaMaterialService
                    .list(Wrappers.lambdaQuery(LitemallOrderFormulaMaterial.class)
                            .eq(LitemallOrderFormulaMaterial::getOrderGoodsId,og.getId()));

            List<LitemallOrderGoodsAccesoryVO> accesoryVos = new ArrayList<>();
			if(!CollectionUtils.isEmpty(orderFormulaMaterials)) {
				for (int i = 0; i < orderFormulaMaterials.size(); i++) {
					LitemallOrderGoodsAccesoryVO accesoryVo = new LitemallOrderGoodsAccesoryVO();
					accesoryVo.setName(orderFormulaMaterials.get(i).getMaterialName());
					accesoryVo.setNumber(orderFormulaMaterials.get(i).getQuantity());
					accesoryVo.setPrice(orderFormulaMaterials.get(i).getPrice());
                    accesoryVos.add(accesoryVo);
				}
			}

            LitemallOrderGoodsVO vs = new LitemallOrderGoodsVO();
            BeanUtils.copyProperties(og, vs);
//            vs.setProperties(sb.toString());
            vs.setSpecifications(ss.toString());
            vs.setAccesoryVos(accesoryVos);
            return vs;
        }).collect(Collectors.toList());



        if (vos.size() > 0) {
            for (int i = 0; i < vos.size(); i++) {
                subTotal = subTotal.add(vos.get(i).getSellingPrice());
            }
        }
        vo.setSubTotal(subTotal);
        vo.setGoods(vos);

        //店面电话号码
        LitemallShop shop = shopService.findById(shopId);
        vo.setStoreNo(shop.getName());
        if (shop != null) {
            vo.setShopMobile(shop.getMobile());
            vo.setShopAddress(shop.getStreetAddress());
            vo.setShopUserId(vo.getUserId());
        }

        if (order.getAddTime() != null) {

            vo.setAddDate(order.getAddTime().toLocalDate().toString());
            vo.setAddTime(order.getAddTime().toLocalTime().toString());
        }

        List<LitemallOrderTax> taxes = litemallOrderTaxService.queryByOrderId(orderId);
        Map<String, BigDecimal> taxMap = new HashMap<>();
        if (taxes.size() > 0) {
            for (int i = 0; i < taxes.size(); i++) {
                if (taxMap.get(taxes.get(i).getCode()) != null) {
                    taxMap.put(taxes.get(i).getCode(), taxMap.get(taxes.get(i).getCode()).add(taxes.get(i).getPrice()));
                } else {
                    taxMap.put(taxes.get(i).getCode(), taxes.get(i).getPrice());
                }
            }
//			vo.setTaxes(taxMap);
        }

        List<TaxStatisticsDetailVo> taxVos = new ArrayList<>();
        taxMap.keySet().forEach(key -> {
            TaxStatisticsDetailVo taxVo = new TaxStatisticsDetailVo();
            taxVo.setCode(key);
            taxVo.setTotalAmount(taxMap.get(key));
            taxVos.add(taxVo);
        });
        vo.setTaxes(taxVos);

        if (Constants.PAY_TYPE_CASH.byteValue() == vo.getPayType()) {
            List<LitemallOrderCash> cashes = litemallOrderCashService.queryByOrderId(orderId);

            if (cashes.size() > 0) {
                LitemallOrderCash cash = cashes.get(0);
                vo.setChange(cash.getChange());
                vo.setCash(cash.getCash());
                vo.setRound(vo.getTotal().subtract(cash.getOrderPrice()));
            }
            vo.setLeft("CASH");
            vo.setMedium("");
            vo.setRight(vo.getTotal().toString());
        } else if (vo.getPayType() == PAY_TYPE_CLOVER.byteValue()) {
            LumiereCloverPayLog log = lumiereCloverPayLogService.queryByOrderId(order.getId().toString());
            if(log != null){
                vo.setLeft(log.getCardType() != null ? log.getCardType() : "");
                vo.setMedium(log.getCardNo() != null ? log.getCardNo() : "");
                vo.setRight(vo.getTotal().toString());
                vo.setCardNo(log.getCardNo());
            }
        } else if (order.getPayType().equals(PAY_TYPE_BALANCE)) { //余额支付
            LitemallUser user = litemallUserService.findById(order.getUserId());
            vo.setPoints(user.getPoints());
            vo.setAvailableAmount(user.getAvailableAmount());
            vo.setUsername(user.getUsername());
            vo.setLeft("STORE CREDIT");
            vo.setMedium(user.getUsername());
            vo.setRight(vo.getTotal().toString());
        } else if (order.getPayType() == PAY_TYPE_GIFT_CARD) {
            LitemallGiftCardUserLog log = litemallGiftCardUserLogService.queryByOrderIdAndType(orderId, (byte) 2);
            if (log != null) {
                LitemallGiftCardUser cardUser = litemallGiftCardUserService.findById(log.getCardUserId());
                if (cardUser != null) {
                    LitemallGiftCard card = giftCardService.findById(cardUser.getGiftCardId());
                    vo.setCardNumber(cardUser.getCardNumber());
                    vo.setLeft(card.getName());
                    vo.setMedium(cardUser.getCardNumber());
                    vo.setRight(vo.getTotal().toString());
                }
            }
        }


        //支付时间
        if (order.getPayTime() != null) {
            vo.setPayDate(order.getPayTime().toLocalDate().toString());
            vo.setPayTim(order.getPayTime().toLocalTime().toString());
        }
        return vo;
    }


    /**
     * 退款
     *
     * @param shopId   商店id
     * @param refundId 退款id
     * @return {@link Object}
     */
    public Object getRefundVo(Integer shopId, Integer refundId) {
        LitemallRefund refund = litemallRefundService.findById(refundId);

        if(refund == null){
            return ResponseUtil.fail(ORDER_REFUND_NOT_EXIST, "退款订单不存在");
        }

        LitemallOrder order = orderService.findById(refund.getOrderId());

        //实时消息通知
        BigDecimal tPrice = new BigDecimal(0.0);
        LitemallRefundVO vo = new LitemallRefundVO();
        LitemallShop refundShop = shopService.findById(shopId);
        vo.setShopAddress(refundShop.getStreetAddress());
        vo.setShopMobile(refundShop.getMobile());
        vo.setShopUserId(order.getUserId());
        vo.setPayType(order.getPayType());
        vo.setMessage(order.getMessage());
        vo.setShopNo(refundShop.getName());
        vo.setStoreNo(refundShop.getName());
        vo.setMemberPer(order.getMemberPer());
        vo.setMemberPrice(order.getMemberPrice());
        vo.setCouponPrice(order.getCouponPrice());
        if (order.getPayTime() != null) {
            vo.setAddDate(order.getPayTime().toLocalDate().toString());
            vo.setAddTime(order.getPayTime().toLocalTime().toString());
        } else {
            vo.setAddDate(order.getAddTime().toLocalDate().toString());
            vo.setAddTime(order.getAddTime().toLocalTime().toString());
        }

        vo.setRefundDate(refund.getAddTime().toLocalDate().toString());
        vo.setRefundTime(refund.getAddTime().toLocalTime().toString());
        vo.setSerinalNumber(order.getSerinalNumber());

        //退款商品信息
        List<LitemallRefundGoods> refundGoods = litemallRefundGoodsService.findByRefundId(refundId);
        if (refundGoods != null && refundGoods.size() > 0) {
            BigDecimal subTotal = new BigDecimal(0.0);
            List<LitemallRefundGoodsVO> ogVos = new ArrayList<>();
            for (int i = 0; i < refundGoods.size(); i++) {
                LitemallRefundGoodsVO ogVo = new LitemallRefundGoodsVO();
                BeanUtils.copyProperties(refundGoods.get(i), ogVo);
               // LitemallGoods rg = goodsService.findById(refundGoods.get(i).getGoodsId());
                LitemallOrderGoods orderGoods = orderGoodsService.findById(refundGoods.get(i).getOrderGoodsId());
                ogVo.setGoodsName(orderGoods.getGoodsName() );
                ogVo.setSpecifications(orderGoods.getSpecifications()[0]);
                ogVo.setGoodsPrice(refundGoods.get(i).getGoodsPrice());
                ogVo.setUnitPrice(orderGoods.getUnitPrice());
                subTotal = subTotal.add(refundGoods.get(i).getGoodsPrice());
                ogVos.add(ogVo);

                //属性
                List<LitemallOrderFormulaMaterial> orderFormulaMaterials = litemallOrderFormulaMaterialService
                        .list(Wrappers.lambdaQuery(LitemallOrderFormulaMaterial.class)
                                .eq(LitemallOrderFormulaMaterial::getOrderGoodsId,orderGoods.getId()));
                List<LitemallOrderGoodsAccesoryVO> orderGoodsAccesoryVOS = CollStreamUtil.toList(orderFormulaMaterials, orderFormulaMaterial -> {
                    LitemallOrderGoodsAccesoryVO accesoryVo = new LitemallOrderGoodsAccesoryVO();
                    accesoryVo.setName(orderFormulaMaterial.getMaterialName());
                    accesoryVo.setNumber(orderFormulaMaterial.getQuantity());
                    accesoryVo.setPrice(orderFormulaMaterial.getPrice());
                    return accesoryVo;
                });
                ogVo.setAccesoryVos(orderGoodsAccesoryVOS);
            }
            vo.setGoods(ogVos);
            vo.setSubTotal(subTotal);
            tPrice = tPrice.add(subTotal);
        }

        //退款税费
        List<TaxStatisticsDetailVo> refundTaxes = litemallRefundTaxService.queryByRefundId(refundId);
        for (int i = 0; i < refundTaxes.size(); i++) {
                                      refundTaxes.get(i).setTotalAmount(refundTaxes.get(i).getTotalAmount());
            tPrice = tPrice.add(refundTaxes.get(i).getTotalAmount());
        }
        vo.setRefundTaxes(refundTaxes);
        vo.setTotal(tPrice);


        //卡信息或者会员信息
        if (order.getPayType() == PAY_TYPE_CLOVER) {
//            if (order.getPayMemberId() != null) {
//                LumiereIdcard idcard = idCardService.findById(order.getPayMemberId());
//                vo.setLeft(idcard.getType());
//                vo.setMedium(idcard.getCardNo());
//                vo.setRight(vo.getTotal().toString());
//            }
            LumiereCloverPayLog log = lumiereCloverPayLogService.queryByOrderId(order.getId().toString());

            if(log != null){
                vo.setLeft(log.getCardType() != null ? log.getCardType() : "");
                vo.setMedium(log.getCardNo() != null ? log.getCardNo() : "");
                vo.setRight(vo.getTotal().toString());
            }

        } else if (order.getPayType() == PAY_TYPE_BALANCE) {
            LitemallUser user = litemallUserService.findById(order.getUserId());
            vo.setLeft("STORE CREDIT");
            vo.setMedium(user.getUsername());
            vo.setRight(vo.getTotal().toString());
        } else if (order.getPayType() == PAY_TYPE_GIFT_CARD) {
            LitemallGiftCardUserLog log = litemallGiftCardUserLogService.queryByOrderIdAndType(order.getId(), (byte) 2);
            if (log != null) {
                LitemallGiftCardUser cardUser = litemallGiftCardUserService.findById(log.getCardUserId());
                if (cardUser != null) {
                    LitemallGiftCard card = giftCardService.findById(cardUser.getGiftCardId());
                    vo.setLeft(card.getName());
                    vo.setMedium(cardUser.getCardNumber());
                    vo.setCardNumber(cardUser.getCardNumber());
                    vo.setRight(vo.getTotal().toString());
                }
            }

        } else {
            vo.setLeft("CASH");
            vo.setRight("");
            vo.setChange(tPrice);
            vo.setCash(new BigDecimal(0.00));
            vo.setMedium(vo.getTotal().toString());
        }
        //vo.setChange(BigDecimal.ZERO);
        vo.setOrderSn(order.getOrderSn());
        return vo;
    }

    /**
     * 得到最后一次下订单
     *
     * @param shopId 商店id
     * @return {@link List}<{@link LitemallOrder}>
     */
    public List<LitemallOrder> getLastOrder(Integer shopId){
        return  orderService.queryLastOrder(shopId);
    }



}
